SQLite з шифруванням / захистом паролем


136

Я просто вчусь використовувати SQLite, і мені було цікаво, чи можливо таке:

  1. Шифрування файлу бази даних?

  2. Захист паролем відкриття бази даних?

PS. Я знаю, що існує таке "розширення шифрування SQLite (SEE).", Але згідно з документацією, "SEE є ліцензованим програмним забезпеченням ...." та "Вартість постійної ліцензії на вихідний код для SEE становить 2000 доларів США".


Це, безумовно, можливо, окрім SEE, існує декілька відкритих рішень. Серед них розширення шифрування, що надходить з wxSQLite3. Детальну інформацію див. У моїй відповіді на подібне запитання.
Ульріх Телле

1
@RobotMess: Чесно кажучи з вами - жоден із перелічених тут. У мене були чіткі обмеження в часі щодо цього проекту, тому мені довелося щось швидко зробити. Я пішов з тим, що я найкраще знав - AES на необроблених даних, перш ніж розміщувати їх у БД ... Це не дуже ефективно, хоча й з точки зору пошуку, пошуку та управління БД.
ahmd0

@ ahmd0 Гм, хіба це не робить БД вигідною? Я маю на увазі, все, що зараз це робиться, це гарантувати, що комісії є атомними.
Навін

Так, це можливо. Якщо націлено на .Net Standard 4.6.1+ або Core, я думаю, що досить просто отримати шифрування Sqlite - це використовувати Microsoft.Data.Sqlite на мою відповідь тут .
paulyb

Відповіді:


110

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

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

SEE та SQLiteCrypt вимагають придбання ліцензії.

Розкриття: я створив botansqlite3.


1
Чи є у вас документація про те, як використовувати Botan для шифрування бази даних SQLite? Веб-сайт Ботану не згадує про цю функцію.
Марк Шльоссер

5
botansqlite3 зараз розповсюджується незалежно від Ботану.
OliJG

1
Існує також література . Він використовує шифр ChaCha, швидше, ніж AES на портативних пристроях на базі ARMv7
Бернардо Рамос

SQLite3 .Net як вбудована підтримка шифрування зараз, що значною мірою скасовує цю відповідь.
Критичний

21

Ви можете захистити паролем SQLite3 DB. Вперше перед тим, як робити будь-які операції, встановіть пароль наступним чином.

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();

Це не дозволить будь-якому редактору GUI переглядати ваші дані. Пізніше, якщо ви хочете змінити пароль, використовуйте conn.ChangePassword("new_password"); Щоб скинути або видалити пароль, використовуйтеconn.ChangePassword(String.Empty);


16
Не працюватиме з відкритим кодом Sqlite. Немає поняття, якою це повинна бути реалізація мови, мова чи API.
mikerobi

1
Як дізнатися, який спосіб шифрування ChangePasswordвикористовується? AES 128? RSA ..?
qakmak

1
RSA 1024 або 2048? Чи може якийсь документ бачити, що більше деталей?
qakmak

Отримайте документи звідси system.data.sqlite.org/index.html/doc/trunk/www/index.wiki
Мангеш

В ході власного тестування я виявив, що SetPasswordметод (в даний час) виявляється в основному марним. Єдиний спосіб, коли мені вдалося отримати System.Data.SQLiteбібліотеку, щоб правильно застосувати пароль, було використовувати ChangePasswordметод. Використовуючи SetPassword( перш ніж викликати Openметод, як це, мабуть, вимагає бібліотека), я все-таки зміг відкрити та відредагувати БД у SQLiteStudio без пароля. Лише я не застосував ChangePasswordметод ( після виклику Openметоду), що програма для введення пароля насправді "застрягла".
G_Hosa_Phat


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. Може знадобитися Visual C ++ Runtime, залежно від завантаженого пакету.

ОНОВЛЕННЯ

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


У моєму конкретному прикладі мені потрібно було .libте, що я міг би вбудувати у свій виконуваний файл. У мене не могло бути жодних задирок.
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.

Щоб розшифрувати, потрібно лише ввести пароль у рядок з'єднання перед тим, як відкрити дзвінок.

        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

Ви завжди можете зашифрувати дані на стороні клієнта. Зауважте, що не всі дані повинні бути зашифровані, оскільки вони мають проблеми з продуктивністю.


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


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');
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.