SQLite với bảo vệ mã hóa / mật khẩu


136

Tôi chỉ đang học cách sử dụng SQLite và tôi đã tò mò nếu điều đó là có thể:

  1. Mã hóa tập tin cơ sở dữ liệu?

  2. Mật khẩu bảo vệ mở cơ sở dữ liệu?

Tái bút Tôi biết rằng có "Phần mở rộng mã hóa SQLite (XEM).", Nhưng theo tài liệu, "XEM là phần mềm được cấp phép ...." và "Chi phí của giấy phép mã nguồn vĩnh viễn cho XEM là 2000 USD."


Điều đó chắc chắn là có thể và tồn tại một số giải pháp nguồn mở bên cạnh XEM. Trong số đó, phần mở rộng mã hóa đi kèm với wxSQLite3. Xem câu trả lời của tôi cho một câu hỏi tương tự để biết chi tiết.
Ulrich Telle

1
@RobotMess: Thành thật với bạn - không ai trong số những người được liệt kê ở đây. Tôi đã hạn chế thời gian nghiêm ngặt cho dự án đó, vì vậy tôi phải làm một cái gì đó nhanh chóng. Tôi đã làm theo những gì tôi biết rõ nhất - AES về dữ liệu thô trước khi đặt nó vào DB ... Nó không hiệu quả lắm mặc dù về mặt tra cứu, tìm kiếm và quản lý DB.
ahmd0

@ ahmd0 Hừm, không làm cho loại DB trở nên vô dụng chứ? Ý tôi là, tất cả những gì nó thực sự làm bây giờ là đảm bảo các cam kết là nguyên tử.
Navin

Vâng nó có thể. Nếu nhắm mục tiêu .Net Standard 4.6.1+ hoặc Core, tôi nghĩ rằng khá đơn giản để có được mã hóa Sqlite là sử dụng Microsoft.Data.Sqlite theo câu trả lời của tôi ở đây .
paulyb

Câu trả lời:


110

SQLite có các hook tích hợp để mã hóa không được sử dụng trong phân phối bình thường, nhưng đây là một vài triển khai tôi biết:

  • XEM - Việc thực hiện chính thức.
  • wxSQLite - Trình bao bọc C ++ kiểu wxWidgets cũng thực hiện mã hóa của SQLite.
  • SQLCodes - Sử dụng libcrypto của openSSL để triển khai.
  • SQLiteCrypt - Triển khai tùy chỉnh, API đã sửa đổi.
  • botansqlite3 - botansqlite3 là một codec mã hóa cho SQLite3 có thể sử dụng bất kỳ thuật toán nào trong Botan để mã hóa.
  • sqleet - một triển khai mã hóa khác, sử dụng các nguyên hàm ChaCha20 / Poly1305. Lưu ý rằng wxSQLite được đề cập ở trên có thể sử dụng điều này như một nhà cung cấp tiền điện tử.

XEM và SQLiteCrypt yêu cầu mua giấy phép.

Tiết lộ: Tôi đã tạo botansqlite3.


1
Bạn có tài liệu nào về mã hóa cơ sở dữ liệu hướng dẫn sử dụng cho cơ sở dữ liệu SQLite không? Trang web Botan không đề cập đến tính năng này.
Marc Schlösser

5
botansqlite3 hiện được phân phối độc lập của Botan.
OliJG

1
Ngoài ra còn có văn học . Nó sử dụng mật mã ChaCha, nhanh hơn AES trên các thiết bị di động dựa trên ARMv7
Bernardo Ramos

SQLite3 .Net như được xây dựng để hỗ trợ mã hóa hiện nay, điều này phần lớn làm mất hiệu lực câu trả lời này.
Krythic

21

Bạn có thể mật khẩu bảo vệ SQLite3 DB. Lần đầu tiên trước khi thực hiện bất kỳ thao tác nào, hãy đặt mật khẩu như sau.

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

sau đó lần sau bạn có thể truy cập nó như thế nào

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

Điều này sẽ không cho phép bất kỳ trình soạn thảo GUI nào xem dữ liệu của bạn. Sau này nếu bạn muốn thay đổi mật khẩu, hãy sử dụng conn.ChangePassword("new_password"); Để đặt lại hoặc xóa mật khẩu, hãy sử dụngconn.ChangePassword(String.Empty);


16
Không hoạt động với Sqlite mã nguồn mở. Không biết việc triển khai ngôn ngữ, ngôn ngữ hoặc API này là gì.
mikerobi

1
Làm thế nào để tôi biết cách mã hóa ChangePasswordđược sử dụng? AES 128? RSA ..?
qakmak

1
RSA 1024 hay 2048? Có tài liệu nào có thể thấy chi tiết hơn không?
qakmak


Trong thử nghiệm của riêng tôi, tôi đã thấy rằng SetPasswordphương pháp (tại thời điểm này) về cơ bản dường như vô dụng. Cách duy nhất tôi có thể khiến System.Data.SQLitethư viện áp dụng đúng mật khẩu là sử dụng ChangePasswordphương thức này. Sử dụng SetPassword( trước khi gọi Openphương thức, theo yêu cầu của thư viện), tôi vẫn có thể mở và chỉnh sửa DB trong SQLiteStudio mà không cần bất kỳ mật khẩu nào. Mãi đến khi tôi sử dụng ChangePasswordphương thức ( sau khi gọi Openphương thức) thì ứng dụng mật khẩu mới thực sự bị "kẹt".
G_Hosa_Tháng

15

Thư viện .net System.Data.SQLite cũng cung cấp mã hóa.


8
ASP.NET! = SQL Server! = Phiên bản cài đặt của SQL Server
Zev Spitz

1
Nhưng System.Data.SQLite không phải từ Microsoft. Câu hỏi này không phải là về .Net nhưng nếu đó là sự tương thích và không tương thích khác sẽ rất quan trọng.
dùng34660

7

Bạn có thể nhận sqlite3.dlltệp với sự hỗ trợ mã hóa từ http://system.data.sqlite.org/ .

1 - Truy cập http://system.data.sqlite.org/index.html/doc/trunk/www/doads.wiki và tải xuống một trong các gói. Phiên bản .NET không liên quan ở đây.

2 - Trích xuất SQLite.Interop.dlltừ gói và đổi tên thành sqlite3.dll. DLL này hỗ trợ mã hóa thông qua mật khẩu văn bản gốc hoặc khóa mã hóa.

Các tập tin được đề cập là bản địa và KHÔNG yêu cầu .NET framework. Nó có thể cần Visual C ++ Runtime tùy thuộc vào gói bạn đã tải xuống.

CẬP NHẬT

Đây là gói mà tôi đã tải xuống để phát triển 32 bit: http://system.data.sqlite.org/blobs/1.0.94.0/sqlite-netFx40-static-binary-Win32-2010-1.0.94.0.zip


Trong ví dụ cụ thể của tôi, tôi cần một .libcái mà tôi có thể nhúng vào tệp thực thi của mình. Tôi không thể có bất kỳ dlls.
ahmd0

2
Vui lòng kiểm tra cái này github.com/rindeal/wxSQLite3-VS sẽ cung cấp cho bạn một tệp libdlltệp.
Mohammad Banisaeid

4

Hãy ghi nhớ, những điều sau đây không nhằm mục đích thay thế cho một giải pháp bảo mật thích hợp.

Sau khi chơi xung quanh vấn đề này trong bốn ngày, tôi đã đưa ra một giải pháp chỉ sử dụng gói System.Data.SQLite nguồn mở từ NuGet. Tôi không biết bao nhiêu sự bảo vệ này cung cấp. Tôi chỉ sử dụng nó cho khóa học của riêng tôi. Điều này sẽ tạo DB, mã hóa nó, tạo bảng và thêm dữ liệu.

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

Tùy chọn, bạn có thể loại bỏ conn.SetPassword(passwordBytes);và thay thế nó bằng conn.ChangePassword("password");cái cần đặt sau conn.Open();thay vì trước. Sau đó, bạn sẽ không cần phương thức GetBytes.

Để giải mã, vấn đề chỉ là đặt mật khẩu trong chuỗi kết nối của bạn trước khi cuộc gọi mở.

        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"- đây là một tuyên bố rất tệ nếu bạn định xử lý mã hóa. Nguyên tắc chung là bạn không bao giờ tự làm điều đó nếu bạn không hiểu nó. Nếu không, tốt hơn hết là bạn không nên sử dụng nó.
ahmd0

Tôi thấy điểm của bạn. Tôi hầu như đang cố gắng sửa lời khuyên mà tôi đã thấy không hoạt động với phiên bản System.Data.Sqlite hiện tại. Tôi không có ý ám chỉ rằng đây là bảo mật tốt. Tôi đã cập nhật bài viết của mình. Cảm ơn các đầu vào!
Mike Warner

2

Bạn luôn có thể mã hóa dữ liệu về phía khách hàng. Xin lưu ý rằng không phải tất cả dữ liệu phải được mã hóa vì nó có vấn đề về hiệu năng.


1

Vâng, SEElà đắt tiền. Tuy nhiên SQLitecó giao diện tích hợp để mã hóa (Pager). Điều này có nghĩa là, bên trên mã hiện tại, người ta có thể dễ dàng phát triển một số cơ chế mã hóa, không cần phải như vậy AES. Cái gì đó thật sự. Vui lòng xem bài viết của tôi ở đây: https://stackoverflow.com/a/49161716/9418360

Bạn cần xác định SQLITE_HAS_CODEC = 1 để bật mã hóa Pager. Mã mẫu bên dưới ( SQLitenguồn gốc):

#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ó một phiên bản thương mại C languageđể SQLitemã hóa bằng AES256 - nó cũng có thể hoạt động PHP, nhưng nó cần được biên dịch PHPSQLitemở rộng. Nó hủy / mã hóa SQLitetệp cơ sở dữ liệu một cách nhanh chóng, nội dung tệp luôn được mã hóa. Rất hữu ích.

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


0

Bạn có thể sử dụng các thói quen tạo chức năng của SQLite ( hướng dẫn sử dụng PHP ):

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

Khi chèn dữ liệu, bạn có thể sử dụng trực tiếp chức năng mã hóa và XÁC NHẬN dữ liệu được mã hóa hoặc bạn có thể sử dụng chức năng tùy chỉnh và chuyển dữ liệu không được mã hóa:

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

Khi truy xuất dữ liệu, bạn cũng có thể sử dụng chức năng tìm kiếm SQL:

$select_obj = $db_obj->prepare('SELECT Clear, ' .
 'Decrypt(Encrypted, "' . $passwordhash_str . '") AS PlainText FROM table ' .
 'WHERE PlainText LIKE :searchterm');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.