SQLite dengan enkripsi / perlindungan kata sandi

141

Saya baru belajar menggunakan SQLite dan saya ingin tahu apakah itu mungkin:

  1. Enkripsi file database?

  2. Kata sandi melindungi pembukaan database?

PS. Saya tahu bahwa ada "SQLite Encryption Extension (SEE)", tetapi menurut dokumentasi, "SEE adalah perangkat lunak berlisensi ...." dan "Biaya lisensi kode sumber abadi untuk SEE adalah US $ 2000."

ahmd0
sumber
Itu pasti mungkin dan ada beberapa solusi open source selain SEE. Diantaranya ekstensi enkripsi datang dengan wxSQLite3. Lihat jawaban saya untuk pertanyaan serupa untuk detailnya.
Ulrich Telle
2
@RobotMess: Sejujurnya dengan Anda - tidak ada yang tercantum di sini. Saya memiliki batasan waktu yang ketat untuk proyek itu, jadi saya harus melakukan sesuatu dengan cepat. Saya menggunakan apa yang paling saya ketahui - AES pada data mentah sebelum memasukkannya ke dalam DB ... Ini tidak terlalu efisien meskipun dalam hal pencarian, pencarian, dan manajemen DB.
ahmd0
@ ahmd0 Hm, bukankah itu membuat DB menjadi tidak berguna? Maksud saya, yang benar-benar dilakukannya sekarang adalah memastikan komitmen bersifat atom.
Navin
Iya itu mungkin. Jika menargetkan .Net Standard 4.6.1+ atau Core, menurut saya cara yang cukup mudah untuk mendapatkan enkripsi Sqlite adalah dengan menggunakan Microsoft.Data.Sqlite sesuai jawaban saya di sini .
paulyb

Jawaban:

114

SQLite memiliki kait bawaan untuk enkripsi yang tidak digunakan dalam distribusi normal, tetapi berikut beberapa implementasi yang saya ketahui:

  • LIHAT - Implementasi resmi.
  • wxSQLite - Pembungkus C ++ gaya wxWidgets yang juga menerapkan enkripsi SQLite.
  • SQLCipher - Menggunakan libcrypto openSSL untuk diimplementasikan.
  • SQLiteCrypt - Implementasi khusus, API yang dimodifikasi.
  • botansqlite3 - botansqlite3 adalah codec enkripsi untuk SQLite3 yang dapat menggunakan algoritme apa pun di Botan untuk enkripsi.
  • sqleet - implementasi enkripsi lain, menggunakan primitif ChaCha20 / Poly1305. Perhatikan bahwa wxSQLite yang disebutkan di atas dapat menggunakan ini sebagai penyedia crypto.

SEE dan SQLiteCrypt memerlukan pembelian lisensi.

Pengungkapan: Saya membuat botansqlite3.

OliJG
sumber
1
Apakah Anda memiliki dokumentasi How-To-Use Botan untuk enkripsi database SQLite? Situs web Botan tidak menyebutkan fitur ini.
Marc Schlösser
6
botansqlite3 sekarang didistribusikan secara independen dari Botan.
OliJG
1
Ada juga litereplica . Ini menggunakan cipher ChaCha, lebih cepat dari AES pada perangkat portabel berbasis ARMv7
Bernardo Ramos
SQLite3 .Net sebagai dukungan bawaan untuk enkripsi sekarang, yang sebagian besar membuat jawaban ini tidak valid.
Krythic
21

Anda dapat melindungi sandi SQLite3 DB. Untuk pertama kalinya sebelum melakukan operasi apa pun, setel sandi sebagai berikut.

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

maka lain kali Anda dapat mengaksesnya seperti

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

Ini tidak akan mengizinkan editor GUI untuk melihat data Anda. Nanti jika Anda ingin mengubah kata sandi, gunakan conn.ChangePassword("new_password"); Untuk mengatur ulang atau menghapus kata sandi, gunakanconn.ChangePassword(String.Empty);

Mangesh
sumber
18
Tidak akan berfungsi dengan Sqlite open source. Tidak tahu apa implementasi bahasa, bahasa, atau API ini seharusnya.
mikerobi
1
Bagaimana saya tahu cara enkripsi yang ChangePassworddigunakan? AES 128? RSA ..?
qakmak
1
RSA 1024 atau 2048? Apakah ada dokumen yang bisa melihat lebih detail?
qakmak
1
Dalam pengujian saya sendiri, saya menemukan bahwa SetPasswordmetode (saat ini) pada dasarnya tampak tidak berguna. Satu-satunya cara saya bisa membuat System.Data.SQLiteperpustakaan menerapkan kata sandi dengan benar adalah menggunakan ChangePasswordmetode ini. Menggunakan SetPassword( sebelum memanggil Openmetode, seperti yang tampaknya diperlukan oleh perpustakaan), saya masih bisa membuka dan mengedit DB di SQLiteStudio tanpa kata sandi. Baru setelah saya menggunakan ChangePasswordmetode ( setelah memanggil Openmetode) aplikasi kata sandi benar-benar "macet".
G_Hosa_Phat
16

Library .net System.Data.SQLite juga menyediakan enkripsi.

Rory
sumber
8
ASP.NET! = SQL Server! = Instance yang diinstal dari SQL Server
Zev Spitz
1
Tetapi System.Data.SQLite bukan dari Microsoft. Pertanyaan ini bukan tentang .Net tetapi jika kemudian kompatibilitas dan ketidaksesuaian lain akan menjadi penting.
pengguna34660
9

Anda bisa mendapatkan sqlite3.dllfile dengan dukungan enkripsi dari http://system.data.sqlite.org/ .

1 - Buka http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki dan unduh salah satu paket. Versi .NET tidak relevan di sini.

2 - Ekstrak SQLite.Interop.dlldari paket dan ubah namanya menjadi sqlite3.dll. DLL ini mendukung enkripsi melalui sandi teks biasa atau kunci enkripsi.

File yang disebutkan adalah asli dan TIDAK memerlukan kerangka .NET. Mungkin perlu Visual C ++ Runtime tergantung pada paket yang telah Anda unduh.

MEMPERBARUI

Ini adalah paket yang saya unduh untuk pengembangan 32-bit: http://system.data.sqlite.org/blobs/1.0.94.0/sqlite-netFx40-static-binary-Win32-2010-1.0.94.0.zip

Mohammad Banisaeid
sumber
Dalam contoh khusus saya, saya membutuhkan .libyang bisa saya masukkan ke dalam executable saya. Saya tidak bisa memiliki dll.
ahmd0
2
Silakan juga periksa github.com/rindeal/wxSQLite3-VS yang satu ini yang akan memberi Anda file libdan dll.
Mohammad Banisaeid
3

Perlu diingat, berikut ini tidak dimaksudkan sebagai pengganti solusi keamanan yang tepat.

Setelah bermain-main dengan ini selama empat hari, saya telah mengumpulkan solusi hanya menggunakan paket System.Data.SQLite open source dari NuGet. Saya tidak tahu seberapa besar perlindungan yang diberikannya. Saya hanya menggunakannya untuk program studi saya sendiri. Ini akan membuat DB, mengenkripsinya, membuat tabel, dan menambahkan data.

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;
        }
    }
}

Secara opsional, Anda dapat menghapus conn.SetPassword(passwordBytes);, dan menggantinya dengan conn.ChangePassword("password");yang harus ditempatkan setelah, conn.Open();bukan sebelumnya. Maka Anda tidak memerlukan metode GetBytes.

Untuk mendekripsi, itu hanya masalah meletakkan kata sandi di string koneksi Anda sebelum panggilan dibuka.

        string filename = @"C:\Programming\sqlite3\db.db";
        string passwordString = "password";
        SQLiteConnection conn = new SQLiteConnection("Data Source=" + filename + ";Version=3;Password=" + passwordString + ";");
        conn.Open();
Mike Warner
sumber
2
"I think I saw 128 bit somewhere"- ini adalah pernyataan yang sangat buruk jika Anda berencana berurusan dengan enkripsi. Aturan praktisnya adalah Anda tidak pernah melakukannya sendiri jika Anda tidak memahaminya. Jika tidak, sebaiknya Anda tidak menggunakannya sama sekali.
ahmd0
Saya mengerti maksud Anda. Saya kebanyakan mencoba untuk memperbaiki saran yang saya lihat yang tidak bekerja dengan versi System.Data.Sqlite saat ini. Saya tidak bermaksud mengatakan bahwa ini adalah keamanan yang baik. Saya telah memperbarui posting saya. Terima kasih atas masukannya!
Mike Warner
SetPassword tidak ada di objek SQLiteConnection, System.Data.SQLite 1.0.113.0
Ejrr1085
2

Anda selalu dapat mengenkripsi data di sisi klien. Harap dicatat bahwa tidak semua data harus dienkripsi karena memiliki masalah kinerja.

Marcin
sumber
1

Yah, SEEitu mahal. Namun SQLitememiliki antarmuka built-in untuk enkripsi (Pager). Artinya, di atas kode yang ada, seseorang dapat dengan mudah mengembangkan beberapa mekanisme enkripsi, tidak harus AES. Apa saja. Silakan lihat posting saya di sini: https://stackoverflow.com/a/49161716/9418360

Anda perlu mendefinisikan SQLITE_HAS_CODEC = 1 untuk mengaktifkan enkripsi Pager. Kode contoh di bawah ( SQLitesumber asli ):

#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

Ada versi komersial C languageuntuk SQLiteenkripsi menggunakan AES256 - ini juga dapat digunakan PHP, tetapi perlu dikompilasi dengan PHPdan SQLiteekstensi. Ini de / mengenkripsi SQLitefile database dengan cepat, konten file selalu dienkripsi. Sangat berguna.

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

q74
sumber
0

Anda dapat menggunakan rutinitas pembuatan fungsi SQLite ( manual PHP ):

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

Saat memasukkan data, Anda dapat menggunakan fungsi enkripsi secara langsung dan MASUKKAN data terenkripsi atau Anda dapat menggunakan fungsi khusus dan meneruskan data yang tidak terenkripsi:

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

Saat mengambil data, Anda juga dapat menggunakan fungsionalitas pencarian SQL:

$select_obj = $db_obj->prepare('SELECT Clear, ' .
 'Decrypt(Encrypted, "' . $passwordhash_str . '") AS PlainText FROM table ' .
 'WHERE PlainText LIKE :searchterm');
Alien426
sumber
0

Saya juga punya masalah serupa. Diperlukan untuk menyimpan data sensitif dalam database sederhana (SQLite adalah pilihan yang tepat kecuali keamanan). Akhirnya saya telah menempatkan file database di TrueCrypt encrypted valume.

Aplikasi konsol tambahan memasang drive sementara menggunakan TrueCrypt CLI dan kemudian memulai aplikasi database. Menunggu hingga aplikasi database keluar dan kemudian turun dari drive lagi.

Mungkin bukan solusi yang cocok di semua skenario tetapi bagi saya bekerja dengan baik ...

Tom
sumber