SQLite с шифрованием / защитой паролем

136

Я только учусь использовать SQLite, и мне было любопытно, если это возможно:

  1. Шифрование файла базы данных?

  2. Пароль защищает открытие базы данных?

PS. Я знаю, что существует это «Расширение шифрования SQLite (SEE)», но согласно документации «SEE - это лицензионное программное обеспечение…» и «Стоимость бессрочной лицензии на исходный код для SEE составляет 2000 долларов США».

ahmd0
источник
Это, безусловно, возможно, и кроме SEE существует несколько решений с открытым исходным кодом. Среди них расширение шифрования, идущее с wxSQLite3. Смотрите мой ответ на аналогичный вопрос для деталей.
Ульрих Телле
1
@RobotMess: Если честно, ни один из перечисленных здесь. У меня были строгие временные ограничения на этот проект, поэтому я должен был что-то сделать быстро. Я пошел с тем, что я знал лучше всего - AES на необработанных данных, прежде чем поместить их в БД ... Это не очень эффективно, хотя с точки зрения поиска, поиска и управления БД.
ahmd0
@ ahmd0 Хм, разве это не делает БД бесполезным? Я имею в виду, что все, что он сейчас делает, это то, что коммиты являются атомарными
Навин
Да, это возможно. Если я нацеливаюсь на .Net Standard 4.6.1+ или Core, я думаю, что довольно просто получить шифрование Sqlite - использовать Microsoft.Data.Sqlite для моего ответа здесь .
Полиб

Ответы:

110

SQLite имеет встроенные хуки для шифрования, которые не используются в обычном выпуске, но вот несколько реализаций, которые я знаю:

  • СМОТРИ - Официальная реализация.
  • wxSQLite - Оболочка C ++ в стиле wxWidgets, которая также реализует шифрование SQLite.
  • SQLCipher - использует libcrypto openSSL для реализации.
  • SQLiteCrypt - Пользовательская реализация, модифицированный API.
  • botansqlite3 - botansqlite3 - кодек шифрования для SQLite3, который может использовать любые алгоритмы в Botan для шифрования.
  • sqleet - еще одна реализация шифрования, использующая примитивы ChaCha20 / Poly1305. Обратите внимание, что упомянутый выше wxSQLite может использовать его как провайдера шифрования.

SEE и SQLiteCrypt требуют покупки лицензии.

Раскрытие: я создал botansqlite3.

OliJG
источник
1
Есть ли у вас документация о том, как использовать Botan для шифрования базы данных SQLite? Веб-сайт Botan не упоминает эту функцию.
Марк Шлёссер
5
botansqlite3 теперь распространяется независимо от Botan.
OliJG
1
Существует также litereplica . Он использует шифр ChaCha, быстрее, чем AES на портативных устройствах на базе ARMv7
Бернардо Рамос
SQLite3 .Net теперь поддерживает встроенную поддержку шифрования, что в значительной степени лишает законной силы этот ответ.
Krythic
21

Вы можете защитить паролем БД SQLite3. В первый раз перед выполнением каких-либо операций установите пароль следующим образом.

SQLiteConnection conn = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;");
conn.SetPassword("password");
conn.open();

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

conn = new SQLiteConnection("Data Source=MyDatabase.sqlite;Version=3;Password=password;");
conn.Open();

Это не позволит любому редактору графического интерфейса просматривать ваши данные. Позже, если вы хотите изменить пароль, используйте conn.ChangePassword("new_password"); Чтобы сбросить или удалить пароль, используйтеconn.ChangePassword(String.Empty);

Mangesh
источник
16
Не будет работать с Sqlite с открытым исходным кодом. Понятия не имею, какой языковой реализацией, языком или API это должно быть.
Микероби
1
Как узнать, какой способ шифрования ChangePasswordиспользуется? AES 128? RSA ..?
qakmak
1
RSA 1024 или 2048? Есть ли какие-нибудь документы, которые могли бы увидеть это более подробно?
qakmak
Получить документы из здесь system.data.sqlite.org/index.html/doc/trunk/www/index.wiki
Mangesh
В моем собственном тестировании я обнаружил, что SetPasswordметод (в настоящее время) кажется в основном бесполезным. Единственный способ заставить System.Data.SQLiteбиблиотеку правильно применить пароль - это использовать ChangePasswordметод. Используя SetPassword( до вызова Openметода, как того требует библиотека), я все еще мог открывать и редактировать БД в SQLiteStudio без какого-либо пароля. Только после того, как я использовал ChangePasswordметод ( после вызова Openметода), приложение пароля фактически "зависло".
G_Hosa_Phat
15

Библиотека .net System.Data.SQLite также обеспечивает шифрование.

Рори
источник
8
ASP.NET! = SQL Server! = Установленный экземпляр SQL Server
Зев Шпиц
1
Но System.Data.SQLite не от Microsoft. Этот вопрос не о .Net, но если бы это было так, то были бы важны другие совместимости и несовместимости.
user34660
7

Вы можете получить sqlite3.dllфайл с поддержкой шифрования на http://system.data.sqlite.org/ .

1 - Перейдите по адресу http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki и загрузите один из пакетов. Версия .NET здесь неактуальна.

2 - Извлечь SQLite.Interop.dllиз пакета и переименовать в sqlite3.dll. Эта DLL-библиотека поддерживает шифрование с помощью незашифрованных паролей или ключей шифрования.

Упомянутый файл является нативным и НЕ требует .NET Framework. Может потребоваться среда выполнения Visual C ++ в зависимости от загруженного пакета.

ОБНОВИТЬ

Это пакет, который я скачал для 32-разрядной разработки: http://system.data.sqlite.org/blobs/1.0.94.0/sqlite-netFx40-static-binary-Win32-2010-1.0.94.0.zip

Мухаммед Банисейд
источник
В моем конкретном примере мне нужно было, .libчтобы я мог встроить в мой исполняемый файл. Я не мог иметь какие-либо DLL.
Ahmd0
2
Пожалуйста, проверьте также этот github.com/rindeal/wxSQLite3-VS, который даст вам файл libи dllфайл.
Мохаммад Банисаид
4

Имейте в виду, что следующее не является заменой правильного решения безопасности.

Поработав с этим в течение четырех дней, я собрал решение, использующее только пакет System.Data.SQLite с открытым исходным кодом от NuGet. Я не знаю, какую защиту это обеспечивает. Я использую его только для собственного курса обучения. Это создаст БД, зашифрует ее, создаст таблицу и добавит данные.

using System.Data.SQLite;

namespace EncryptDB
{
    class Program
    {
        static void Main(string[] args)
        {
            string connectionString = @"C:\Programming\sqlite3\db.db";
            string passwordString = "password";
            byte[] passwordBytes = GetBytes(passwordString);
            SQLiteConnection.CreateFile(connectionString);
            SQLiteConnection conn = new SQLiteConnection("Data Source=" + connectionString + ";Version=3;");
            conn.SetPassword(passwordBytes);
            conn.Open();
            SQLiteCommand sqlCmd = new SQLiteCommand("CREATE TABLE data(filename TEXT, filepath TEXT, filelength INTEGER, directory TEXT)", conn);
            sqlCmd.ExecuteNonQuery();
            sqlCmd = new SQLiteCommand("INSERT INTO data VALUES('name', 'path', 200, 'dir')", conn);
            sqlCmd.ExecuteNonQuery();
            conn.Close();
        }
        static byte[] GetBytes(string str)
        {
            byte[] bytes = new byte[str.Length * sizeof(char)];
            bytes = System.Text.Encoding.Default.GetBytes(str);
            return bytes;
        }
    }
}

При желании вы можете удалить conn.SetPassword(passwordBytes);и заменить его на то, conn.ChangePassword("password");что нужно разместить после, conn.Open();а не перед. Тогда вам не понадобится метод GetBytes.

Чтобы расшифровать, нужно просто ввести пароль в строку подключения перед вызовом open.

        string filename = @"C:\Programming\sqlite3\db.db";
        string passwordString = "password";
        SQLiteConnection conn = new SQLiteConnection("Data Source=" + filename + ";Version=3;Password=" + passwordString + ";");
        conn.Open();
Майк Уорнер
источник
2
"I think I saw 128 bit somewhere"- это очень плохое утверждение, если вы планируете заниматься шифрованием. Эмпирическое правило заключается в том, что вы никогда не делаете это сами, если не понимаете этого. В противном случае вам лучше не использовать его вообще.
ahmd0
Я понимаю вашу точку зрения. Я в основном пытался исправить совет, который я видел, который не работает с текущей версией System.Data.Sqlite. Я не хотел подразумевать, что это была хорошая безопасность. Я обновил свой пост. Спасибо за вклад!
Майк Уорнер
2

Вы всегда можете зашифровать данные на стороне клиента. Обратите внимание, что не все данные должны быть зашифрованы, поскольку они имеют проблемы с производительностью.

Marcin
источник
1

Ну, SEEэто дорого. Однако SQLiteимеет встроенный интерфейс для шифрования (пейджер). Это означает, что поверх существующего кода можно легко разработать какой-то механизм шифрования, не обязательно AES. Ничего действительно. Пожалуйста, смотрите мой пост здесь: https://stackoverflow.com/a/49161716/9418360

Вам необходимо определить SQLITE_HAS_CODEC = 1, чтобы включить шифрование пейджера. Пример кода ниже ( SQLiteпервоисточник):

#ifdef SQLITE_HAS_CODEC
/*
** This function is called by the wal module when writing page content
** into the log file.
**
** This function returns a pointer to a buffer containing the encrypted
** page content. If a malloc fails, this function may return NULL.
*/
SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
  void *aData = 0;
  CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
  return aData;
}
#endif

Существует коммерческая версия в C languageтечение SQLiteшифрования с помощью AES256 - он также может работать с PHP, но он должен быть собран с PHPи SQLiteрасширением. Он дешифрует SQLiteфайл базы данных на лету, содержимое файла всегда зашифровано. Очень полезно.

http://www.iqx7.com/products/sqlite-encryption

Q74
источник
0

Вы можете использовать подпрограммы создания функций SQLite ( руководство по PHP ):

$db_obj->sqliteCreateFunction('Encrypt', 'MyEncryptFunction', 2);
$db_obj->sqliteCreateFunction('Decrypt', 'MyDecryptFunction', 2);

При вставке данных вы можете использовать функцию шифрования напрямую и ВСТАВИТЬ зашифрованные данные или использовать пользовательскую функцию и передавать незашифрованные данные:

$insert_obj = $db_obj->prepare('INSERT INTO table (Clear, Encrypted) ' .
 'VALUES (:clear, Encrypt(:data, "' . $passwordhash_str . '"))');

При получении данных вы также можете использовать функцию поиска SQL:

$select_obj = $db_obj->prepare('SELECT Clear, ' .
 'Decrypt(Encrypted, "' . $passwordhash_str . '") AS PlainText FROM table ' .
 'WHERE PlainText LIKE :searchterm');
Alien426
источник