SQLite พร้อมการเข้ารหัส / การป้องกันรหัสผ่าน


141

ฉันเพิ่งเรียนรู้ที่จะใช้ SQLite และฉันอยากรู้ว่าเป็นไปได้หรือไม่:

  1. การเข้ารหัสไฟล์ฐานข้อมูล?

  2. รหัสผ่านป้องกันการเปิดฐานข้อมูล?

ปล. ฉันรู้ว่ามี "SQLite Encryption Extension (SEE)" แต่ตามเอกสาร "SEE เป็นซอฟต์แวร์ที่ได้รับอนุญาต .... " และ "ค่าใช้จ่ายของใบอนุญาตซอร์สโค้ดแบบถาวรสำหรับ SEE คือ 2,000 ดอลลาร์สหรัฐ"


เป็นไปได้อย่างแน่นอนและมีโซลูชันโอเพ่นซอร์สหลายอย่างนอกเหนือจาก SEE ในบรรดาส่วนขยายการเข้ารหัสที่มาพร้อมกับ wxSQLite3 ดูคำตอบของฉันสำหรับคำถามที่คล้ายกันสำหรับรายละเอียด
Ulrich Telle

2
@RobotMess: ความซื่อสัตย์กับคุณ - ไม่มีรายการใดที่ระบุไว้ที่นี่ ฉันมีข้อ จำกัด ด้านเวลาที่เข้มงวดในโครงการนั้นดังนั้นฉันจึงต้องทำอะไรบางอย่างอย่างรวดเร็ว ฉันไปกับสิ่งที่ฉันรู้ดีที่สุด - AES กับข้อมูลดิบก่อนวางลงในฐานข้อมูล ... มันไม่ค่อยมีประสิทธิภาพแม้ว่าในแง่ของการค้นหาการค้นหาและการจัดการฐานข้อมูล
ahmd0

@ ahmd0 หืมนั่นไม่ทำให้ DB ไร้ประโยชน์เหรอ? ฉันหมายความว่าสิ่งที่ทำตอนนี้คือให้แน่ใจว่าคอมมิตเป็นปรมาณู
นาวิน

ใช่มันเป็นไปได้ หากกำหนดเป้าหมายสุทธิมาตรฐาน 4.6.1+ หรือแกนผมคิดว่าตรงไปตรงมาเป็นธรรมที่จะได้รับการเข้ารหัส Sqlite คือการใช้ Microsoft.Data.Sqlite ต่อคำตอบของฉันที่นี่
paulyb

คำตอบ:


114

SQLite มี hooks ในตัวสำหรับการเข้ารหัสซึ่งไม่ได้ใช้ในการแจกจ่ายปกติ แต่นี่คือการใช้งานบางส่วนที่ฉันรู้:

  • ดู - การนำไปใช้อย่างเป็นทางการ
  • wxSQLite - WxWidgets style C ++ wrapper ที่ใช้การเข้ารหัสของ SQLite ด้วย
  • SQLCipher - ใช้ libcrypto ของ openSSL เพื่อใช้งาน
  • SQLiteCrypt - การใช้งานแบบกำหนดเอง, API ที่แก้ไข
  • botansqlite3 - botansqlite3 เป็นตัวแปลงสัญญาณการเข้ารหัสสำหรับ SQLite3 ที่สามารถใช้อัลกอริทึมใด ๆ ใน Botan สำหรับการเข้ารหัส
  • sqleet - การใช้งานการเข้ารหัสอื่นโดยใช้ ChaCha20 / Poly1305 primitives โปรดทราบว่า wxSQLite ที่กล่าวถึงข้างต้นสามารถใช้สิ่งนี้เป็นผู้ให้บริการ crypto

SEE และ SQLiteCrypt จำเป็นต้องซื้อใบอนุญาต

การเปิดเผยข้อมูล: ฉันสร้าง botansqlite3


1
คุณมีเอกสาร How-To-Use Botan สำหรับการเข้ารหัสฐานข้อมูล SQLite หรือไม่? เว็บไซต์โบตั๋นไม่ได้กล่าวถึงคุณสมบัตินี้
Marc Schlösser

6
botansqlite3 ได้รับการแจกจ่ายอย่างอิสระของ Botan
OliJG

1
นอกจากนี้ยังมีlitereplica ใช้รหัส ChaCha เร็วกว่า AES บนอุปกรณ์พกพาที่ใช้ ARMv7
Bernardo Ramos

SQLite3 .Net ที่สร้างขึ้นเพื่อรองรับการเข้ารหัสในขณะนี้ซึ่งส่วนใหญ่จะทำให้คำตอบนี้ไม่ถูกต้อง
Krythic

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


18
จะไม่ทำงานกับ Sqlite โอเพนซอร์ส ไม่มีเงื่อนงำการใช้ภาษาภาษาหรือ API ที่ควรจะเป็น
mikerobi

1
ฉันจะรู้ได้อย่างไรว่าChangePasswordใช้วิธีการเข้ารหัสแบบใด AES 128? อาร์เอส .. ?
qakmak

1
RSA 1024 หรือ 2048? มีเอกสารใดบ้างที่สามารถดูรายละเอียดเพิ่มเติมได้
qakmak

รับเอกสารจากที่นี่system.data.sqlite.org/index.html/doc/trunk/www/index.wiki
Mangesh

1
ในการทดสอบของฉันเองฉันพบว่าSetPasswordวิธีการ (ในเวลานี้) ดูเหมือนจะไร้ประโยชน์โดยทั่วไป วิธีเดียวที่ฉันจะได้รับSystem.Data.SQLiteไลบรารีเพื่อใช้รหัสผ่านอย่างถูกต้องคือการใช้ChangePasswordวิธีนี้ เมื่อใช้SetPassword( ก่อนที่จะเรียกใช้Openเมธอดตามที่ไลบรารีต้องการ) ฉันยังคงสามารถเปิดและแก้ไข DB ใน SQLiteStudio ได้โดยไม่ต้องใช้รหัสผ่าน จนกระทั่งฉันใช้ChangePasswordเมธอด ( หลังจากเรียกOpenเมธอด) ว่าแอปพลิเคชันรหัสผ่าน "ค้าง" จริงๆ
G_Hosa_Phat

16

ไลบรารี. net System.Data.SQLiteยังจัดเตรียมสำหรับการเข้ารหัส


8
ASP.NET! = SQL Server! = อินสแตนซ์ที่ติดตั้งของ SQL Server
Zev Spitz

1
แต่System.Data.SQLiteไม่ได้มาจาก Microsoft คำถามนี้ไม่เกี่ยวกับ. Net แต่ถ้าเป็นเช่นนั้นความเข้ากันได้อื่น ๆ และความเข้ากันไม่ได้จะมีความสำคัญ
user34660

9

คุณจะได้รับ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.dllDLL นี้รองรับการเข้ารหัสผ่านรหัสผ่านข้อความธรรมดาหรือคีย์เข้ารหัส

ไฟล์ที่กล่าวถึงเป็นไฟล์ดั้งเดิมและไม่จำเป็นต้องใช้. NET framework อาจต้องใช้ 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ที่ฉันสามารถฝังลงในไฟล์ปฏิบัติการได้ ฉันไม่มี dll เลย
ahmd0

2
โปรดตรวจสอบgithub.com/rindeal/wxSQLite3-VSนี้ด้วยซึ่งจะให้ไฟล์libและdllไฟล์
Mohammad Banisaeid

3

โปรดทราบว่าสิ่งต่อไปนี้ไม่ได้มีไว้เพื่อทดแทนโซลูชันด้านความปลอดภัยที่เหมาะสม

หลังจากเล่นกับสิ่งนี้เป็นเวลาสี่วันฉันได้รวบรวมวิธีแก้ปัญหาโดยใช้แพคเกจ 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 เวอร์ชันปัจจุบัน ฉันไม่ได้ตั้งใจจะบอกเป็นนัยว่านี่คือความปลอดภัยที่ดี ฉันได้อัปเดตโพสต์ของฉันแล้ว ขอบคุณสำหรับข้อมูล!
Mike Warner

SetPassword ไม่มีอยู่ในวัตถุ SQLiteConnection, System.Data.SQLite 1.0.113.0
Ejrr1085

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

0

ฉันก็มีปัญหาที่คล้ายกัน จำเป็นในการจัดเก็บข้อมูลที่ละเอียดอ่อนในฐานข้อมูลอย่างง่าย (SQLite เป็นตัวเลือกที่สมบูรณ์แบบยกเว้นความปลอดภัย) ในที่สุดฉันก็วางไฟล์ฐานข้อมูลไว้ในค่าที่เข้ารหัส TrueCrypt

แอปคอนโซลเพิ่มเติมจะติดตั้งไดรฟ์ชั่วคราวโดยใช้ TrueCrypt CLI จากนั้นจึงเริ่มแอปพลิเคชันฐานข้อมูล รอจนกว่าแอ็พพลิเคชันฐานข้อมูลจะออกจากนั้นจึงถอดไดรฟ์อีกครั้ง

อาจจะไม่ใช่วิธีแก้ปัญหาที่เหมาะสมในทุกสถานการณ์ แต่สำหรับฉันทำงานได้ดี ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.