Шифрование SQLite - PullRequest
       2

Шифрование SQLite

5 голосов
/ 05 декабря 2011

Я собираюсь написать свое собственное шифрование, но хотел бы обсудить некоторые внутренние вопросы. Должен использоваться на нескольких мобильных платформах - iOS, Android, WP7 с рабочим столом, более или менее выступающим в качестве тестовой платформы.

Давайте начнем с кратких характеристик существующих решений:

  • Стандартное (коммерческое) расширение SE для SQLite - я понятия не имею, как оно работает внутри компании и как оно взаимодействует с упомянутыми мобильными платформами.

  • System.data.sqlite (только для Windows): RC4 шифрование полной базы данных, режим ECB. Они также шифруют заголовок БД, что иногда (с вероятностью 0,01%) приводит к повреждению БД. *) Дополнительное преимущество: они используют объединение SQLite.

  • SqlCipher (openssl, то есть несколько платформ): выбираемая схема шифрования. Они шифруют всю БД. Режим CBC (я думаю), случайный вектор IV. Из-за этого они должны изменить параметры страницы (размер + зарезервированное пространство для хранения IV). Они осознали проблемы, связанные с незашифрованным чтением заголовка БД, и попытались ввести обходные пути, но решение было неудовлетворительным. Дополнительный недостаток: они используют исходное дерево SQLite3. (Что, с другой стороны, обеспечивает дополнительные функции, то есть точную настройку параметров шифрования с использованием специальных прагм.)

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

  • Шифрование всей БД, кроме заголовка БД.
  • Режим ECB: звучит рискованно, но после краткого изучения формата DB я не могу представить, как это можно использовать для атаки.
  • AES128?
  • Реализация поверх объединения SQLite (аналогично system.data.sqlite)

Я хотел бы обсудить возможные проблемы этой схемы шифрования.

*) Из-за чтения SQLite заголовок БД без расшифровки. Благодаря RC4 (потоковому шифру) эта проблема проявится только при первом использовании. AES будет намного опаснее, поскольку каждая «живая» БД рано или поздно столкнется с этой проблемой.


EDITED - случай шифрования на основе VFS

Вышеупомянутые методы используют методологию на основе кодеков, одобренную sqlite.org. Это набор из 3 обратных вызовов, наиболее важный из которых:

void *(*xCodec)(void *iCtx, void *data, Pgno pgno, int mode)

Этот обратный вызов используется по усмотрению SQLite для шифрования / дешифрования данных, считываемых / записываемых на диск. Данные обмениваются постранично. (Страница кратна 512 By.)

Альтернативный вариант - использовать VFS. VFS - это набор обратных вызовов, используемых для низкоуровневых OS-сервисов. Среди них есть несколько связанных с файлами сервисов, например, XOpen / xSeek / xRead / xWrite / xClose. В частности, здесь приведены методы, используемые для обмена данными

int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst);

Размер данных в этих вызовах варьируется от 4 By (частый случай) до размера страницы БД. Если вы хотите использовать блочный шифр (что еще использовать?), То вам необходимо организовать базовый блочный кеш. Я не могу представить реализацию, которая была бы такой же безопасной и эффективной, как встроенные транзакции SQLite.

Вторая проблема: реализация VFS зависит от платформы. В Android / iOS / WP7 / для настольных компьютеров используются разные источники, т. Е. Шифрование на основе VFS должно быть реализовано для каждой платформы.

Следующая проблема является более тонкой: платформа может использовать VFS-вызовы для реализации блокировки файлов. Эти виды использования не должны быть зашифрованы. Более того, общие блокировки не должны буферизироваться. Другими словами, шифрование на уровне VFS может поставить под угрозу функциональность блокировки.


EDITED - атака открытым текстом на VFS-шифрование

Я понял это позже: заголовок БД начинается с фиксированной строки «SQLite format 3», а заголовок содержит множество других фиксированных байтовых значений. Это открывает двери для известных атак открытым текстом (KPA).

В основном это проблема шифрования на основе VFS, поскольку в нем нет информации о том, что заголовок БД шифруется.

System.data.sqlite также имеет эту проблему, поскольку он шифрует (RC4) также заголовок БД.

SqlCipher перезаписывает строку hdr солью, используемой для преобразования пароля в ключ.Более того, по умолчанию используется AES, поэтому атака KPA не представляет опасности.

Ответы [ 2 ]

4 голосов
/ 05 декабря 2011

Вам не нужно взламывать формат БД или исходный код sqlite.SQLite предоставляет API-интерфейс виртуальной файловой системы (vfs), который можно использовать для упаковки файловой системы (или другой vfs) на уровень шифрования, который шифрует / дешифрует страницы на лету.Когда я это сделал, это оказалось очень простой задачей, всего сто строк кода или около того.Таким образом, вся БД будет зашифрована, включая файл журнала, и она полностью прозрачна для любого клиентского кода.При типичном размере страницы 1024 можно использовать практически любой известный блочный шифр.Из того, что я могу сделать вывод из их документации, именно это и делает SQLCipher.

Что касается «проблем», которые вы видите:

  • Вам не нужно переопределять поддержку файловой системы,Вы можете обернуть вокруг VFS по умолчанию.Так что никаких проблем с блокировками или зависимостью от платформы.
  • Бэкэнд ОС SQLite по умолчанию также VFS, нет никаких накладных расходов на использование VFS, кроме того, что вы добавляете.
  • Вам не нужен блочный кеш.Конечно, вам придется читать весь блок, когда он запрашивает всего 4 байта, но не кэшируйте его, он никогда не будет прочитан снова.SQLite имеет свой собственный кеш для предотвращения этого (модуль Pager).
1 голос
/ 07 декабря 2011

Не получил большого ответа, поэтому вот мое решение:

  • Собственное шифрование (AES128), режим CBC

  • Интерфейс кодека(используется SqlCipher или system.data.sqlite)

  • незашифрованный заголовок БД

  • Заголовки страниц также не зашифрованы и используются для генерации IV

  • Использование объединенного распределения SQLite

AFAIK Это решение должно быть лучше, чем SqlCipher или system.data.sqlite.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...