![]() |
|
|||
WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
Этот файл описывает SQLite Encryption Extension (SEE) for SQLite.
SEE позволяет SQLite читать и писать зашифрованные файлы базы данных.
Все содержание базы данных, включая метаданные, зашифровано так, чтобы
внешнему наблюдателю база данных казалась белым шумом.
Версия SQLite с SEE также в состоянии прочитать и написать нормальные
файлы базы данных, созданные обычной версией SQLite.
Но общественная версия SQLite не будет в состоянии прочитать или написать
зашифрованный файл базы данных. Действительно, никакая версия любого
известного программного обеспечения не будет в состоянии получить доступ к
зашифрованному файлу базы данных, не зная ключ шифрования.
SEE на самом деле ряд расширений, использующих различные алгоритмы
шифрования. Следующие алгоритмы шифрования в настоящее время поддерживаются:
Основная библиотека SQLite находится в общественном достоянии.
Однако, расширения чтобы прочитать и написать зашифрованный файл базы данных
это лицензируемое программное обеспечение. Необходимо быть в состоянии видеть
это программное обеспечение, если у вас есть лицензия.
Ваша лицензия бесконечная. Вы внесли однократную плату, которая позволяет
вам использовать и изменять программное обеспечение навсегда. Можно отправить
столько копий программного обеспечения клиентам, сколько вы хотите, пока вы
гарантируете, что только собранные двоичные модули
отправлены (вы не можете распространять исходный код), и что ваши клиенты не
могут сделать дополнительные копии программного обеспечения, чтобы
использовать для других целей.
Можно создать многократные продукты, которые используют это программное
обеспечение, пока все продукты развиваются той же самой командой.
В целях этого параграфа "команда" это
рабочая единица, где все знают имена других. Если вы находитесь в крупной
компании, где этот продукт используется многократными командами, то каждая
команда должна приобрести собственную отдельную лицензию
или корпоративную лицензию.
Ваше приложение рассматривает SEE как единственный большой файл C-кода,
который является общедоступной заменой для
объединения SQLite.
Файл исходного кода SEE работает и собирается точно так же, как объединение
public-domain "sqlite3.c". Если вы уже создаете свое приложение, используя
файл public-domain "sqlite3.c", то чтобы собрать с использованием SEE, вы
просто заменяете файл public-domain "sqlite3.c" на SEE-версию
"sqlite3.c" и пересобираете проект.
Есть девять различных SEE-файлов "sqlite3.c", чтобы выбрать из:
Рекомендуемая процедура добавления SEE в ваше приложение:
скопировать один из этих файлов в ваше дерево исходного кода
приложения, переименовав его в "sqlite3.c", перезаписав public-domain
"sqlite3.c", и скомпилировать проект. После перекомпилирования ваше
приложение должно продолжить работать точно, как это сделало прежде, читая и
сохраняя обычные незашифрованные базы данных SQLite. Как только вы повторно
собрали и проверили, что все все еще работает, добавьте PRAGMA
(описан ниже), который активирует шифрование к вашему коду приложения.
Следующее это файлы исходного кода, используемые, чтобы осуществить
SQLite Encryption Extension:
Этот файл это общедоступная замена для public-domain "sqlite3.c",
добавляя поддержку шифрования, используя AES-256 в режиме OFB, связывая с
внешней библиотекой OpenSSL. Этот файл это общедоступная замена для public-domain "sqlite3.c",
добавляя поддержку шифрования, используя AES-256 в режиме OFB,
используя нативный интерфейс CryptoAPI в Windows. Этот файл это общедоступная замена для public-domain "sqlite3.c",
добавляя поддержку шифрования, используя AES-256 в режиме OFB,
используя встроенную копию Rijndaal. Этот файл это общедоступная замена для public-domain "sqlite3.c",
добавляя поддержку шифрования AES-128 и AES-256 в режиме OFB, используя
внешнее шифрование CCCrypt. CCCrypt это библиотека шифрования по умолчанию в
MacOS и iOS и таким образом, это внедрение SEE рекомендуется
для тех платформ.
Модуль see-ccrypt.c обычно делает только шифрование AES128. Однако,
когда see-cccrypt собран с -DCCCRYPT256, он будет использовать AES256 если и
только если ключ точно 32 байта длиной. Этот файл это общедоступная замена для public-domain "sqlite3.c",
добавляя поддержку шифрования AES-128 в режиме OFB, используя Rijndaal. Этот файл это общедоступная замена для public-domain "sqlite3.c",
добавляя поддержку шифрования AES-128 в режиме CCM. Режим CCM
включает код аутентификации сообщения, который обеспечивает идентификацию в
дополнение к конфиденциальности. Это использует Rijndaal для AES. Этот файл это общедоступная замена для public-domain "sqlite3.c",
добавляя поддержку шифрования RC4. RC4 больше не считают безопасным. Вы не
должны использовать это внедрение SEE. Это обеспечивается только
для исторической совместимости. Этот файл это общедоступная замена для public-domain "sqlite3.c",
добавляя поддержку шифрования RC4, AES128-OFB или AES258-OFB.
Используемый алгоритм основан на префиксе к ключу шифрования.
Если ключевой материал начинается с "rc4:", используется RC4.
Если ключевой материал начинается с "aes128:", используется AES128-OFB.
Если ключевой материал начинается с "aes256:", используется AES256-OFB.
Если ни один из этих трех действительных префиксов не появляется в
ключе, то AES128-OFB используется по умолчанию. Действительный префикс удален
из ключа до того как он будет передан алгоритму шифрования. Этот файл это общедоступная замена для public-domain "sqlite3.c",
добавляя поддержку псевдошифрование, которое делает не что иное, как XOR базы
данных против повторной копии ключа шифрования. Этот вариант SEE не
обеспечивает истинное шифрование. Это только для демонстрационного
использования или для использования в случаях, где желательно запутать файл
базы данных, на самом деле не шифруя его, возможно
из-за юридических ограничений. Копия незашифрованного SQLite, которая содержит дополнительные
перехватчики, чтобы добавить шифрование.
Другие зашифрованные модули SQLite выше это
копии этого файла с дополнительным кодом, предварительно дописанные,
чтобы сделать работу шифрования. Этот файл обеспечивается только для ссылки и
вероятно не полезен для развития. Этот файл содержит интерфейсные определения для SQLite. Для других
программ, которые связываются с SQLite, будет нужен этот файл, и вам будет
нужен этот файл, чтобы собрать CLI, но вам не нужен этот файл, чтобы
собрать сам SQLite. Этот файл содержит исходный код для "CLI",
программы Command Line Interface "sqlite3.exe",
которую можно использовать, чтобы получить доступ и управлять файлами базы
данных SQLite. Этот файл отличается от "shell.c" в версии public-domain
SQLite. Этот shell.c был увеличен, чтобы использовать расширение шифрования.
Чтобы собрать SEE в статическую библиотеку, выберите соответствующий файл
"sqlite3-see-*.c" (содержащий алгоритм и внедрение, которое вы желаете),
затем соберите тот файл точно так же, как вы собрали бы обычный
public-domain "sqlite3.c". В unix последовательность команд была бы
чем-то вроде этого:
В windows команды больше похожи на это:
Мы поощряем вас статически связывать SQLite со своим приложением.
Однако, если необходимо использовать SQLite в качестве отдельной DLL или
разделяемой библиотеки, можно собрать следующим образом в Linux:
Или под Windows:
Чтобы собрать CLI, просто передайте исходный файл shell.c
своему компилятору C вместе со статической библиотекой, подготовленной выше,
или с кодовыми файлами первоисточника. Типичная команда в Linux:
На Mac:
В Windows с MSVC:
Для добавления улучшения производительности при сборке
CLI, рассмотрите добавление опции -DSQLITE_THREADSAFE=0. CLI однопоточна,
и SQLite работает быстрее, если это не должно использовать свой mutexes.
SEE можно также собрать для Windows Phone 8,
UWP 10 и Android.
CLI это то же самое, что и
CLI в public-domain SQLite
хотя с улучшениями, чтобы поддержать шифрование. Есть новые параметры
командной строки ("-key", "-hexkey" и "-textkey")
для определения ключа шифрования. Примеры:
Если ключ опущен или является пустой строкой, никакое
шифрование не выполняется.
Есть три различных формата ключа. Первый формат (-key)
берет строку ключа и повторяет его много раз, пока это не превышает число
байтов в ключе основного алгоритма (16 байтов для AES128, 32 байта для AES256
или 256 байтов для RC4). Это тогда усекает результат к размеру ключа
алгоритма. Этот подход ограничивает ключевое пространство, так как это не
позволяет 0x00 байты в ключе. Второй формат (-hexkey)
принимает ключ как шестнадцатеричный, таким образом, любой ключ может быть
представлен. Если обеспеченный ключ слишком длинный, он усекается.
Если обеспеченный ключ слишком короткий,
он повторяется, чтобы заполнить его до длины ключа алгоритма.
Третий формат (-textkey) вычисляет сильный хэш на входном материале ключа и
применяет его в качестве ключа алгоритма. Формат -textkey рекомендуется
для новых приложений.
SEE-CLI также включает новые
dot-команды
".rekey", ".hex-rekey" и ".text-rekey" для изменения ключа шифрования:
Первый аргумент всегда старый пароль в формате, как это поставлялось
опции "-key", "-hexkey" или "-textkey", когда инструмент командной строки был
запущен. Если база данных была ранее не зашифрована, используйте пустую
строку ("") как ключ. Второй и третий аргументы это
новый ключ шифрования. Необходимо ввести новый ключ дважды, чтобы проверить
на опечатки. Чтобы зашифровать ранее незашифрованную базу
данных, сделайте это:
Шаг VACUUM не требуется, чтобы позволять шифрование, но это настоятельно
рекомендовано. Команда VACUUM гарантирует, что у каждой страницы файла базы
данных есть безопасный nonce.
VACUUM необходим только когда существующий непустой файл базы
данных зашифрован впервые.
Чтобы расшифровать базу данных делают это:
Команда .rekey работает толькр с текстовыми ключами. Чтобы rekey БД,
которая содержит двоичные ключи, используют команду ".hex-rekey". Команда
.hex-rekey работает аналогично .rekey, но новый ключ задан как
шестнадцатеричные символы вместо текста. Команда ".text-rekey"
вычисляет хэш аргумента NEW и использует его как ключ шифрования.
Если вы развертываете расширение шифрования SQLite как DLL или
разделенную библиотеку, необходимо сначала активировать библиотеку, вызвав:
Аргумент это ваш ключ активации продукта. Ключ активации доступен как
простой текст в исходном коде, таким образом, можно ясно видеть, каков он.
Цель ключа активации состоит в том, чтобы препятствовать тому, чтобы один из
ваших клиентов извлек библиотеку SQLite и использовал ее отдельно от
приложения. Без ключа активации, который необходимо знать, пользователи будут
неспособны получить доступ к функциям шифрования.
Если вы неспособны вызвать C-интерфейс sqlite3_activate_see()
(возможно, потому что вы получаете доступ к SQLite через слой обертки),
можно также альтернативно активировать опции шифрования, используя PRAGMA:
Используйте sqlite3_open() API,
чтобы открыть зашифрованную базу данных или любую базу данных, которую вы
хотите обработать rekey. Немедленно после открытия, определите ключ,
используя sqlite3_key_v2():
Если pKey = NULL или nKey = 0,
то база данных, как предполагается, не зашифрована. nKey может быть
произвольно большим, хотя только первые 256 байтов (RC4), 16 байтов (AES128)
или 32 байта (AES256) будут использоваться.
В версиях SEE 3.15.0 и позже, если nKey отрицателен, то pKey, как
предполагается, является законченной нолем последовательностью пароля.
В этом случае пароль хэшируется, и уже этот хэш
используется в качестве ключа к алгоритму AES.
Сам пароль используется в качестве ключа для RC4.
ВНИМАНИЕ: возможность использования хэша пароля,
когда nKey <0 была добавлена в версии 3.15.0. Если вы будете использовать
nKey <0 в какой-либо версии SEE до 3.15.0, шифрование будет тихо
отключено, так же, как если бы вы установили nKey=0.
Модуль see-ccrypt.c по умолчанию использует AES128.
Однако, если see-ccrypt.c собран с -DCCCRYPT256 и интерфейс
sqlite3_key_v2() вызван с nKey=32, шифрование AES256
используется вместо этого.
Если вы определите неправильный ключ, вы не получите сообщение об ошибке
сразу же. Но в первый раз, когда вы пытаетесь получить доступ к базе данных,
вы получите ошибку SQLITE_NOTADB с сообщением
"file is encrypted or is not a database".
zDbName указывает, какая база данных ATTACH должна получить ключ.
Обычно это "main". Можно передать указатель NULL как псевдоним для "main".
Если у вас нет серьезного основания сделать иначе, лучше передайте NULL
для параметра zDbName.
Можно изменить ключ в базе данных, используя sqlite3_rekey():
Ключ NULL расшифровывает базу данных.
Повторный ввод данных требует, чтобы каждая страница файла базы данных
была прочитана, расшифрована, повторно зашифрована с новым ключом, затем
записана снова. Следовательно, повторный ввод данных может занять много
времени на большей базе данных.
Большинство вариантов SEE позволяют вам шифровать существующую базу
данных, которая была создана, используя версию public domain SQLite.
Это невозможно, используя версию подтверждения расширения шифрования в
see-aes128-ccm.c. Если вы действительно зашифруете базу данных, которая была
создана с версией public domain SQLite, nonce не будет использоваться, и файл
будет уязвим для нападения выбранного простого текста. Если вы вызовете
sqlite3_key_v2() сразу после sqlite3_open(),
когда вы сначала создадите базу данных, пространство будет зарезервировано в
базе данных для данного случая, и шифрование будет намного более сильным.
Если вы не хотите шифровать сразу же, вызовите sqlite3_key_v2()
так или иначе с ключом NULL, и пространство специально для данного случая
будет зарезервировано в базе данных даже при том, что никакое шифрование
не сделано первоначально.
Версия public domain библиотеки SQLite может прочитать и написать
зашифрованную базу данных с ключом NULL. Вам нужно расширение шифрования
только если ключ не NULL.
Как альтернатива запросу sqlite3_key_v2(), чтобы установить ключ
декодирования для базы данных, можно вызвать pragma:
Необходимо вызвать этот pragma прежде, чем попытаться сделать любое другое
взаимодействие с базой данных. pragma key работает только со строковыми
ключами. При использовании двоичного ключа, используйте hexkey
pragma вместо этого:
Для эквивалента опции --textkey, в которой текстовый пароль хэшируется,
чтобы вычислить фактический ключ шифрования, используйте:
Используйте pragma rekey, hexrekey или textrekey,
чтобы изменить ключ. Так, например, чтобы изменить ключ на 'demo2':
С помощью этих pragma никогда не необходимо непосредственно вызывать
sqlite3_key_v2() или sqlite3_rekey_v2().
Это означает, что SEE может использоваться с языковыми обертками, которые
не знают о тех интерфейсах.
PRAGMA "key", "hexkey" и "textkey" ожидают те же самые строки ключа, как
аргументы оболочки командной строки "-key", "-hexkey" и "-textkey".
PRAGMA key возвратит последовательность "ok",
если успешно загрузят ключ шифрования в SEE. Если вы вызываете один из этих
pragma на системе, которая не поддерживает шифрование, или если операция по
загрузке ключа терпит неудачу по какой-либо причине, то ничто не возвращено.
Обратите внимание на то, что строка "ok"
возвращена, когда любой ключ загружается, не обязательно правильный ключ.
Единственный способ определить, правилен ли ключ, состоит в том, чтобы
попытаться читать из файла базы данных.
Неправильный ключ приведет к ошибке чтения.
Ключ для приложенной базы данных определяется, используя пункт KEY в конце
запроса ATTACH. Примерно так:
Если KEY пропустить, тот же самый ключ используется, который используется
в настоящее время главной базой данных. Поэтому если приложенная база данных
не зашифрована, определите пустую строку как ключ.
Аргумент ключевого слова KEY может быть постоянным BLOB:
Используя текст, как KEY в ATTACH
ожидает тот же самый ключ, как можно было бы обеспечить для опции "-key" в
оболочке командной строки. Значение BLOB для KEY требует
использовать тот же самый ключ, как был бы предоставлен для опции "-hexkey".
Нет никакого механизма для определения пароля, который будет хэшироваться
для ATTACH. При использовании хэшированного ключа, необходимо вычислить хэш
самому и поставлять его как BLOB.
Сумма ключевого материала, на самом деле используемого расширением
шифрования, зависит, на котором варианте SEE вы работаете.
В see-rc4.c первые 256 байтов ключа используются. В see-aes128-ofb и
see-aes128-ccm используются первые 16 байтов ключа. В see-aes256-ofb
используются первые 32 байта ключа.
Если вы определяете ключ, который короче, чем максимальная длина
ключа, то ключевой материал повторяется много раз по мере необходимости,
чтобы закончить ключ. Если вы определяете ключ, который больше, чем
максимальная длина ключа, то избыточный материал тихо проигнорирован.
Для опции "-textkey" до 256 байтов пароля хэшируются, используя RC4, и
значение хэш-функции становится ключом шифрования.
Обратите внимание на то, что в этом контексте алгоритм RC4 используется
в качестве хеш-функции, а не в качестве шифровальной функции,
таким образом, то, что RC4 шифровальным образом слабый алгоритм, не важно.
Для "sqlite3-see.c" ключ может начаться с префикса, чтобы определить
который алгоритм использовать. Префикс должен быть точно одним из
"rc4:", "aes128:" или "aes256:". Префикс не используется в качестве части
ключа, посланного в алгоритм шифрования. Таким образом, реальный ключ должен
начаться на первом байте после префикса.
Примите во внимание следующие важные детали:
Префикс чувствительный к регистру. "aes256:" это
действительный префикс, но не "AES256:". Если ключевой префикс опущен или написан c орфографическими ошибками,
то алгоритм шифрования по умолчанию "aes128", а
префикс с орфографической ошибкой становится частью ключа. Алгоритм шифрования может быть изменен, используя sqlite3_rekey_v2()
или команду .rekey. Например, чтобы преобразовать
RC4-зашифрованную БД в AES-256:
Строки префиксов алгоритма работают только в "sqlite-see.c".
Для любого из внедрений SEE любой префикс ключа интерпретируется
как часть ключа. nKey в sqlite3_key() и sqlite3_key_v2()
должен включать размер префикса в дополнение к размеру ключа. При использовании PRAGMA hexkey или PRAGMA hexrekey
ключевой префикс должен быть шестнадцатерично закодирован
точно так же, как остальная часть ключа.
Шифрование намного более безопасно, если у него есть случайное значение
на каждой странице базы данных. Без nonce шифрование может быть сломано,
используя нападение выбранного простого текста.
Пуристы будут утверждать (справедливо), что шифрование слабо без nonce.
Число байтов nonce на каждой странице базы данных определяется байтом 20
из файла базы данных. Это значение установлено к нолю по умолчанию в базах
данных, созданных версией public-domain SQLite.
Можно изменить этот байт на положительное значение, управляя командой
VACUUM, используя
версию SEE SQLite.
Можно проверить размер nonce для БД при помощи команды
".dbinfo" в обычной программе
sqlite3.exe.
Вывод команды ".dbinfo" будет выглядеть примерно так:
Байты 16-23 из базы данных не зашифрованы. Таким образом можно всегда
проверять, сколько nonce используется, даже на зашифрованном файле базы
данных, только смотря на байт 20. Рекомендуется, чтобы любой продукт, который
использует шифрование, проверил этот байт, чтобы удостовериться, что это
устанавливается в 4, 12 или 32 а не 0.
Размер nonce может быть увеличен, но не уменьшен с одним
из следующих подходов:
Из оболочки командной строки:
Через C API:
Используя SEE в приложении, рекомендуется, чтобы вы перепроверили это, что
все осуществляется правильно, и что вы получаете устойчивое шифрование,
выполняя как минимум следующие тесты:
Каждая страница зашифрована отдельно. Ключ к шифрованию это
комбинация номера страницы, случайный nonce (если есть) и ключ базы данных.
Данные зашифрованы в главной базе данных и в журнале обратной перемотки или
файле WAL, но не зашифрованы в памяти. Это означает, что, если противник в
состоянии рассмотреть память, используемую вашей программой, он будет в
состоянии видеть незашифрованные данные.
Значение nonce меняется rollback.
see-aes128-ccm.c использует AES в режиме CCM с 16 байтами случайного
nonce на каждой странице и 16-байтовый код аутентификации сообщения (MAC).
Таким образом с crypto3ccm.c 32 байта каждой базы данных страницы заняты
шифрованием и идентификацией как издержки. Следовательно, файлы базы данных,
созданные с использованием crypto3ccm.c, могут быть немного больше.
Кроме того, потому что MAC вычисляется каждый раз, когда страница изменяется,
и проверяется, когда страница будет прочитана, crypto3ccm.c
часто будет немного медленнее. Такова стоимость идентификации.
Как собрать и применить SEE
1. Основы
2. Лицензия
3. Как компилировать
3.1. Файлы исходного кода в дистрибутиве SEE
3.2. Сборка кода SEE
gcc -c sqlite3-see-aes256-ofb.c
ar a sqlite3-see-aes256-ofb.a sqlite3-see-aes256-ofb.o
cl -c sqlite3-see-aes256-ofb.c
lib /out:libsee.lib sqlite3-see-aes256-ofb.obj
3.3. Сборка разделяемых библиотек или DLL
gcc -fPIC -shared -o libsee.so sqlite3-see-aes256-ofb.c
cl -DSQLITE_API=__declspec(dllexport) sqlite3-see-aes256-ofb.c /link \
/dll /out:libsee.dll
3.4. Сборка программы Command-Line Shell
gcc -o sqlite3 shell.c sqlite3-see-aes256-ofb.c -lpthread -ldl
gcc -o sqlite3 shell.c sqlite3-see-aes256-ofb.c -ldl
cl /Fesqlite3.exe shell.c sqlite3-see-aes256-ofb.c
4. Использование командной строки
sqlite3 -key secret database.db
sqlite3 -hexkey 736563726574 database.db
sqlite3 -textkey secret2 database.db
4.1. Изменение ключа шифрования
.rekey OLD NEW NEW
.hex-rekey OLD NEW NEW
.text-rekey OLD NEW NEW
.rekey "" new-key new-key
VACUUM
.rekey old-key "" ""
5. C-интерфейс
sqlite3_activate_see("7bb07b8d471d642e");
PRAGMA activate_extensions='see-7bb07b8d471d642e';
int sqlite3_key_v2(
sqlite3 *db, /* The connection from sqlite3_open() */
const char *zDbName, /* Which ATTACHed database to key */
const void *pKey, /* The key */
int nKey /* Number of bytes in the key */
);
int sqlite3_rekey_v2(
sqlite *db, /* Database to be rekeyed */
const char *zDbName, /* Which ATTACHed database to rekey */
const void *pKey,
int nKey /* The new key */
);
6. Применение PRAGMA "key"
PRAGMA key='your-secret-key';
PRAGMA hexkey='796f75722d7365637265742d6b6579';
PRAGMA textkey='your-secret-key';
PRAGMA rekey='demo2';
PRAGMA hexrekey='64656d6f32';
PRAGMA textrekey='long-passphrase';
7. Применение команды ATTACH
ATTACH DATABASE 'file2.db' AS two KEY 'xyzzy';
ATTACH DATABASE 'file2.db' AS two KEY X'78797a7a79';
8. Ключевой материал
8.1. Выбор алгоритма шифрования, используя ключевой префикс
.rekey rc4:mykey aes256:mykey aes256:mykey
PRAGMA hexkey='aes128:6d796b6579'; -- Ошибка!
PRAGMA hexkey='6165733132383a6d796b6579'; -- Правильно.
9. Важное про Nonce
database page size: 4096
write format: 1
read format: 1
reserved bytes: 12 ← размер Nonce
file change counter: 3504448735
database page count: 14190
freelist page count: 0
schema cookie: 107
schema format: 4
default cache size: 0
autovacuum top root: 0
incremental vacuum: 0
text encoding: 1 (utf8)
user version: 0
application id:0
software version:3008008
number of tables:53
number of indexes: 53
number of triggers: 0
number of views: 0
schema size: 14257
.filectrl reserve_bytes 32
VACUUM;
int nNonce = 32;
sqlite3_file_control(db, "main", SQLITE_FCNTL_RESERVE_BYTES, &nNonce);
sqlite3_exec(db, "VACUUM;", 0, 0, 0);
10. Контрольный список безопасности
Ограничения
11. Как работает SEE
Найди своих коллег! |