Я собираюсь написать свое собственное шифрование, но хотел бы обсудить некоторые внутренние вопросы. Должен использоваться на нескольких мобильных платформах - 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 не представляет опасности.