SQLite: шифрование базы данных в Qt

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 12:24, 27 мая 2018.

SQLite — реляционная СУБД, содержащаяся в библиотеке программирования C. В отличие от многих других СУБД, SQLite не клиент–серверная СУБД, а является компактной встраиваемой. SQLite поддерживает динамическое типизирование данных. Возможные типы полей: INTEGER, REAL, TEXT, BLOB.

Сама библиотека SQLite написана на C; существует большое количество привязок к другим языкам программирования, в том числе Delphi, C++, Java, C#, VB.NET, Python, Perl, Node.js, PHP, PureBasic, Tcl (средства для работы с Tcl включены в комплект поставки SQLite), Ruby, Haskell, Scheme, Smalltalk, Lua и Parser, а также ко многим другим [Источник 1].

Qt — кроссплатформенный фреймворк для разработки программного обеспечения на языке программирования C++. Есть также «привязки» ко многим другим языкам программирования: Python — PyQt, PySide; Ruby — QtRuby; Java — Qt Jambi; PHP — PHP-Qt и другие.

Со времени своего появления в 1996 году библиотека легла в основу многих программных проектов. Кроме того, Qt является фундаментом популярной рабочей среды KDE, входящей в состав многих дистрибутивов Linux [Источник 2].

Решения для шифрования в SQLite

Для шифрования в SQLite были найдены следующие возможные решения:

  • SEE [1] — официальная реализация.
  • wxSQLite [2] — c++ wxWidgets обертка для шифрования SQLite.
  • SQLCipher [3] — использует в реализации openSSL.
  • SQLiteCrypt [4] — модифицированная реализация API.
  • botansqlite3 [5] — шифрующий кодек для SQLite3 использующий библиотеку botan.
  • SQLiteCrypto — java API для Android, использует AES-256 и SHA-256.
  • QtCipherSqlitePlugin [6] — SQL плагин для Qt с поддержкой шифрования.

В данной статье рассмотрим QtCipherSqlitePlugin. Плагин шифрует «на лету» и полностью интегрирован в API Qt.

Плагин базируется на исходниках SQLite а также wxSQLite3 из wxWidgets и выпущен под лицензией LGPL 2.1. В качестве алгоритма шифрования используется Advanced Encryption Standard (AES) [Источник 3].

Подготовка к установке

Для того, чтобы все работало корректно нужно установить компилятор g++ и Qt.

Установка g++

На Ubuntu g++ устанавливается командой:

$ sudo apt-get install g++ 

Устаноквка Qt

Необходимо скачать установочный пакет Qt с официального сайта[7] Запустить, далее выбрать нужную версию Qt, а также Tools. При правильной установке, все должно успешно завершиться и работать.

Видео по установке

Для более подробной и наглядной информации по установке, рекомендуется ознакомится с видео, представленном ниже.

Сборка и установка плагина

Скачиваем исходники QtCipherSqlitePlugin

Плагин можно скачать напрямую из GitHub. Для это необходимо ввести команду:

$ git clone https://github.com/devbean/QtCipherSqlitePlugin 

Также можно скачать архив с официального сайта[8] или необходимую версию отсюда [9].

Скачиваем исходники Qt

Скачиваем исходники Qt необходимой версии (в примере — 4.8.6)

$ wget download.qt.io/archive/qt/4.8/4.8.6/qt-everywhere-opensource-src-4.8.6.tar.gz 

Распаковка архива

Распаковываем полученный архив

$ tar zxvf qt-everywhere-opensource-src-4.8.6.tar.gz 

Открытие проекта

Откроем проект в QtCreator QtCipherSqlitePlugin\sqlitecipher\sqlitecipher.pro

Подготовка с сборке проекта

Версия 0.5+

Из этой версии удалили закрытые заголовки Qt. В этой версии не нужно редактировать какой-либо код в этом проекте. Скомпилировать плагин довольно просто, достаточно просто открыть .pro с помощью QtCreator и собрать проект [Источник 4].

Примечания

Обратите внимание, что отладочная версия была переименована в sqlitecipher_debug на Mac OS.

Версия 0.2-0.4

В файле QtCipherSqlitePlugin\sqlitecipher\qt_p.pri в строчках

# Qt4
!greaterThan(QT_MAJOR_VERSION, 4): INCLUDEPATH += <Qt4_Path>/src/sql/kernel
# Qt5
greaterThan(QT_MAJOR_VERSION, 4): INCLUDEPATH += <Qt5_Path>/Src/qtbase/src/sql/kernel

Задать соответствующие пути к исходникам Qt.

~/qt-everywhere-opensource-src-4.8.6/src/sql/kernel

Версия 0.1

  • Перейти в папку SQLite_cipher, скомпилировать код в этом каталоге. В этом каталоге можно использовать makefile. После компиляции вы получите libsqlite.a или sqlite.lib.
  • скопируйте libsqlite.a или sqlite.lib в sqlitecipher/lib.
  • Перейдите в папку sqlitecipher, здесь вы можете найти qsql_sqlite.cpp. Найдите строку
qlite3_key(d->access, "Trucc", 5);
в функции
bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, const QString &, int, const QString &conOpts)
Здесь строка "Trucc" является паролем для SQLite и 5 – это длина для строки пароля. Вы должны изменить его на свой собственный пароль.
  • Скомпилируйте плагин Qt с помощью sqlitecipher.pro.
  • В результате Вы должны получить sqlitecipher.dll или sqlitecipherd.dll, если нет какой-либо ошибки.

Сборка проекта

Собираем проект sqlitecipher.pro

Копируем библиотеку плагина в директорию плагинов Qt

Необходимо скопировать скомпилированные dll (sqlitecipher(д).dll и sqlitecipher (d).lib для Qt 4 и sqlitecipher(d).dll для Qt5) в каталог плагинов Qt plugins/sqldrivers или использовать команду:

$ make install 

Использование плагина

Проверяем работоспособность

Запустив приложение из проекта QtCipherSqlitePlugin/test/test.pro убеждаемся, что драйвер базы данных SQLITECIPHER появился в списке доступных драйверов.

$ 
(«QSQLITE», «SQLITECIPHER»)
1: «AAA»
2: «BBB»
3: «CCC»
3: «DDD»
4: «EEE»
5: «FFF»
6: «GGG»

или Вы можете использовать этот оператор, чтобы проверить, загружен ли плагин:

qDebug() << QSqlDatabase::drivers();

Если Вы на выходе получили SQLITECIPHER, значит все установлено успешно.

Использование QSqlDatabase

Если плагин в порядке, Вы можете использовать QSqlDatabase для работы с базой данных SQLite.

QSqlDatabase dbconn = QSqlDatabase::addDatabase("SQLITECIPHER");
// Задайте имя базы данных
dbconn.setDatabaseName("test.db");
// Укажите пароль
// Оставьте его пустым, если Вы не хотите использовать пароль
dbconn.setPassword("password");
if (!dbconn.open()) {
    qDebug() << "Can not open connection: " << dbconn.lastError().driverText();
    exit(CONNECTION_FAILED);
}

QSqlQuery query;
// Ваш код ...
...
// Не забудьте закрыть соединение
dbconn.close();

Дополнительные параметры подключения (версия 0.4)

Вы можете установить больше вариантов подключения с помощью этого плагина [Источник 5].

  1. Плагин Qt Sqlite
    1. QSQLITE_BUSY_TIMEOUT
    2. QSQLITE_OPEN_READONLY
    3. QSQLITE_OPEN_URI
    4. QSQLITE_ENABLE_SHARED_CACHE
  2. Плагин QtCipherSqlitePlugin
    1. QSQLITE_CREATE_KEY
    2. QSQLITE_UPDATE_KEY
    3. QSQLITE_REMOVE_KEY

Используйте следующие параметры подключения:

db.setConnectOptions("QSQLITE_BUSY_TIMEOUT=5000;QSQLITE_CREATE_KEY");

Шифрование существующей базы данных

Если вы хотите зашифровать существующую базу данных, которая не имеет пароля, используйте QSQLITE_CREATE_KEY и установите пароль для QSqlDatabase:

QSqlDatabase dbconn = QSqlDatabase::addDatabase("SQLITECIPHER");
dbconn.setDatabaseName("test.db");
dbconn.setPassword("test");
dbconn.setConnectOptions("QSQLITE_CREATE_KEY");

Обновление пароля

Если вы хотите обновить пароль базы данных, используйте QSQLITE_UPDATE_KEY, задайте старый пароль для QSqlDatabase и укажите новый с помощью QSQLITE_UPDATE_KEY:

QSqlDatabase dbconn = QSqlDatabase::addDatabase("SQLITECIPHER");
dbconn.setDatabaseName("test.db");
dbconn.setPassword("test"); // введите старый пароль
dbconn.setConnectOptions("QSQLITE_UPDATE_KEY=newtest"); // введите новый пароль

Сброс пароля

Если вы хотите удалить пароль, используйте QSQLITE_REMOVE_KEY и укажите старый пароль для QSqlDatabase:

QSqlDatabase dbconn = QSqlDatabase::addDatabase("SQLITECIPHER");
dbconn.setDatabaseName("test.db");
dbconn.setPassword("test");
dbconn.setConnectOptions("QSQLITE_REMOVE_KEY");

Пример создания шифрованной БД

Удаляем файл test_c.db, созданный в ходе выполнения приложения test. В коде main.cpp проекта test.pro перед подключением к БД устанавливаем пароль.

dbconn.setPassword("password");

Запускаем приложение, будет создана тестовая БД. Закрываем его, меняем пароль, повторно запускаем, видим, что доступа с неверным паролем к БД нет.

Видео-инструкция по установке QtCipherSqlitePlugin

Для наглядной информации по сборке и установке плагина рекомендуется посмотреть видео-инструкцию представленную ниже. В данном видео также присутствуют простые примеры по использованию данного плагина.

Вывод

SQLite — легковесная встраиваемая реляционная база данных. В стандартном варианте хранит данные в файле в не зашифрованном виде. Для шифрования в SQLite существует несколько решений.

SEE, SQLiteCrypt and SQLiteCrypto требуют приобретения лицензии. SQLCipher доступен в версии Community Edition, но требует libcrypto. Наиболее интересным решением из представленного списка является QtCipherSqlitePlugin.

Qt - это полноценная платформа разработки с инструментами, предназначенными для оптимизации создания приложений и пользовательских интерфейсов для настольных, встраиваемых и мобильных платформ.

Плагин Qt для шифрования SQLite основан на исходниках SQLite и wxSQLite3 из wxWidget. wxSQLite3 включает в себя дополнительное расширение для SQLite, поддерживающее шифрование файлов базы данных на основе ключей с использованием 128-битного шифрования AES.

Считается, что используемый в Advanced Encryption Standard ключ длиной в 128 бит – достаточно надежная защита против лобовой атаки, то есть с чисто математической точки зрения подобрать один правильный пароль из всех возможных – трудноосуществимая задача. Несмотря даже на некоторые недостатки AES, взломать защищенную с помощью этого алгоритма информацию практически нереально [Источник 6].

Таблица ниже показывает возможное число комбинаций с учетом размера ключа:

Возможное число комбинаций с учетом размера ключа
Размер ключа Возможное число комбинаций
1 бит 2
2 бит 4
4 бит 16
8 бит 256
16 бит 65536
32 бит 4.2 * 109
56 бит (DES) 7.2 * 1016
64 бит 1.8 * 1019
128 бит (AES) 3.4 * 1038
192 бит (AES) 6.2 * 1057
256 бит (AES) 1.1 * 1077

Обратите внимание на то, что по мере увеличения размера ключа количество комбинаций возрастает экспоненциально. Математические исчисления доказывают, что размер ключа в 128 бит надежнейшим образом защищает от лобовой атаки:

Предполагаемое время взлома с учетом размера ключа
Размер ключа Предполагаемое время взлома
56 бит 399 секунд
128 бит 1.02 * 1018 лет
192 бит 1.872 * 1037 лет
256 бит 3.31 * 1056 лет

Таким образом, даже суперкомпьютеру понадобилось бы неисчислимо огромное количество времени, чтобы получить доступ к информации под защитой AES посредством лобовой атаки.

Следовательно, выбранное решение для шифрования в SQLite является довольно оптимальным и надежным.

Источники

  1. SQLite // Wikipedia. [2018]. Дата обновления: 16.05.2018. URL: https://ru.wikipedia.org/wiki/SQLite (дата обращения: 16.05.2018).
  2. Qt // Wikipedia. [2018]. Дата обновления: 15.05.2018. URL: https://ru.wikipedia.org/wiki/Qt (дата обращения: 16.05.2018).
  3. Шифрование SQLite базы данных в Qt // Хабр. [2018]. Дата обновления: 17.02.2015. URL: https://habr.com/post/216739/ (дата обращения: 16.05.2018).
  4. How to compile // GitHub. [2018]. Дата обновления: 08.04.2017. URL: https://github.com/devbean/QtCipherSqlitePlugin/wiki/How-to-compile (дата обращения: 16.05.2018).
  5. How to use // GitHub. [2018]. Дата обновления: 08.04.2017. URL: https://github.com/devbean/QtCipherSqlitePlugin/wiki/How-to-compile (дата обращения: 16.05.2018).
  6. Алгоритм шифрования AES // OpenGSM. [2018]. Дата обновления: 12.11.2015. URL: https://www.opengsm.com/blog/algoritm-shifrovaniya-aes/ (дата обращения: 16.05.2018).

Ссылки

  1. SQLite Encryption Extension - SQLite [Официальный сайт] / Дата обращения: 07.05.2018. — URL: https://www.sqlite.org/see/doc/trunk/www/index.wiki
  2. wxSQLite -Sourceforge [Электронный ресурс] / Дата обращения: 07.05.2018. — URL: https://sourceforge.net/projects/wxsqlite/files/
  3. Full Database Encryption for SQLite -Zetetic [Электронный ресурс] / Дата обращения: 07.05.2018. — URL: https://www.zetetic.net/sqlcipher/
  4. SQLite Database Encryption -Sqlite-crypt [Официальный сайт] / Дата обращения: 07.05.2018. — URL: http://sqlite-crypt.com/documentation.htm
  5. BotanSqlite3 -GitHub [Электронный ресурс] / Дата обращения: 07.05.2018. — URL: https://github.com/OlivierJG/botansqlite3
  6. QtCipherSqlitePlugin -GitHub [Электронный ресурс] / Дата обращения: 07.05.2018. — URL: https://github.com/devbean/QtCipherSqlitePlugin
  7. Install Qt -Qt [Официальный сайт] / Дата обращения: 11.05.2018. — URL: https://www.qt.io/download-qt-installer?hsCtaTracking=9f6a2170-a938-42df-a8e2-a9f0b1d6cdce%7C6cb0de4f-9bb5-4778-ab02-bfb62735f3e5
  8. QtCipherSqlitePlugin -QtCipherSqlitePlugin.Galaxyworld [Электронный ресурс] / Дата обращения: 07.05.2018. — URL: http://qtciphersqliteplugin.galaxyworld.org
  9. QtCipherSqlitePlugin - DevHub.io [Электронный ресурс] / Дата обращения: 07.05.2018. — URL: https://devhub.io/repos/devbean-QtCipherSqlitePlugin