Как стать автором
Обновить

Комментарии 11

Судя по статье, вас вполне устроил бы интерфейс с методом dbconn.enableEncryption();
Подскажите, где такой интерфейс с таким методом найти?
Нерешенный вопрос

Осталось непонятным, как поменять пароль для уже созданной и зашифрованной по этому паролю БД.


Смена пароля предусмотрена. Для этого есть такой метод как sqlite3_rekey.

/*
** Change the key on an open database. If the current database is not
** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
** database is decrypted.
**
** The code to implement this API is not available in the public release
** of SQLite.
*/
SQLITE_API int sqlite3_rekey(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The new key */
);
SQLITE_API int sqlite3_rekey_v2(
sqlite3 *db, /* Database to be rekeyed */
const char *zDbName, /* Name of the database */
const void *pKey, int nKey /* The new key */
);
Да, все верно. Но как это сделать в рамках Api QSqlDatabase?
Тут выход наверно только через QSqlDriver.
Примерно как-то так:

QSqlDriver *driver = m_db.driver();
QVariant handle = driver->handle();
Q_ASSERT_X(handle.isValid(), Q_FUNC_INFO, "Invalid handle of QSqlDriver");

if (handle.isValid() && qstrcmp(handle.typeName(), "sqlite3*") != 0)
    return;

sqlite3* db = *static_cast<sqlite3* const*>(handle.data());
if (db == nullptr)
    return;

sqlite3_rekey(db, pKey, nKey);
Это надо делать include заголовочного файла SQLite, который в плагине используется.

Что если переопределить в плагине setPassword таким образом, что когда БД еще не открыта, то setPassword устанавливается для connection, а когда БД уже открыта, то setPassword выполняет sqlite3_rekey?
Не слишком мудрено получится?
Шифруются данные в БД или полностью файл(ы) БД?
При попытке обращения к БД с помощью sqlite3 выдается сообщение об ошибке:
Error: file is encrypted or is not a database

Таким образом можно сделать вывод о том, что шифруется файл полностью (структура БД также скрыта).
Это, скорее, говорит об изменении заголовка, по которому движок определяет [версию] структуры файла данных
Данные расшифровываются при каждом обращении или частично хранятся в расшифрованном виде в памяти (кэш)? первое опасно — в случае даже незначительного повреждения файла можно гарантированно потерять все денные, второе — не безопасно
Шифратор (дешифратор) устанавливается как кодек для pager-а.
Место pager-а в архитектуре SQLite — на рисунке.


В случае любого, даже незначительного повреждения файла невозможно гарантированно восстановить все данные и из незашифрованной БД, если такой механизм не предусмотрен в самой БД. А если восстановить почти все, то потом еще нужно найти то, что испортилось. Для восстановления (на мой взгляд) стоит предусмотреть резервное копирование (бэкапы/дампы).

В любом случае, принимая решение о использовании этого плагина для критически важных данных, потребуется провести его оценку (как минимум по быстродействию и по эффективности шифрования (действительно ли нет незашифрованных данных в временных файлах, например).
А какой самый простой способ интегрировать шифрование SQLite в мобильное приложение на Qt, учитывая управление зависимостями и сборку под разные платформы?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории