具有加密/密码保护的SQLite


136

我只是在学习使用SQLite,我很好奇是否可行:

  1. 加密数据库文件?

  2. 密码保护打开数据库?

PS。我知道这里有“ SQLite加密扩展(SEE)”,但是根据文档,“ SEE是许可软件....”和“ SEE的永久源代码许可的成本为2000美元”。


当然可以,除了SEE之外,还有几种开源解决方案。其中wxSQLite3附带的加密扩展。有关详细信息,请参见我对类似问题的回答。
Ulrich Telle

1
@RobotMess:老实说,这里没有列出。我在那个项目上有严格的时间限制,所以我必须快速做些事情。我采用了我最了解的方法-在将原始数据放入数据库之前先对原始数据进行AES处理……虽然在查找,搜索和数据库管理方面效率不高。
ahmd0

@ ahmd0嗯,这不是使数据库有点用吗?我的意思是,现在真正要做的就是确保提交是原子的。
纳文2013年

是的,有可能。如果以.Net Standard 4.6.1+或Core为目标,我认为获得Sqlite加密的一个相当简单的方法是根据此处的答案使用Microsoft.Data.Sqlite 。
paulyb '18

Answers:


110

SQLite内置了用于加密的钩子,这些钩子在正常发行版中没有使用,但是我知道一些实现:

  • SEE-官方实施。
  • wxSQLite-一个wxWidgets样式的C ++包装器,也实现了SQLite的加密。
  • SQLCipher-使用openSSL的libcrypto实施。
  • SQLiteCrypt-自定义实现,已修改的API。
  • botansqlite3 -botansqlite3是SQLite3的加密编解码器,可以使用Botan中的任何算法进行加密。
  • sqleet-使用ChaCha20 / Poly1305原语的另一种加密实现。请注意,上面提到的wxSQLite可以将其用作加密提供程序。

SEE和SQLiteCrypt需要购买许可证。

披露:我创建了botansqlite3。


1
您是否有任何有关如何使用Botan进行SQLite数据库加密的文档?Botan网站没有提及此功能。
MarcSchlösser'02

5
botansqlite3现在独立于Botan分发。
OliJG 2012年

1
也有文学。它使用ChaCha的密码,比AES快基于ARMv7的便携设备
贝尔纳多·拉莫斯

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


16
不适用于开源Sqlite。不知道这应该是哪种语言实现,语言或API。
mikerobi 2014年

1
我怎么知道使用哪种加密方式ChangePassword?AES 128?RSA ..?
qakmak 2015年

1
RSA 1024或2048?有没有文件可以看到更多详细信息?
qakmak '16


在我自己的测试中,我发现该SetPassword方法(目前)似乎基本无用。我能够使System.Data.SQLite库正确应用密码的唯一方法是使用ChangePassword方法。使用SetPassword调用该Open方法之前,这显然是库所要求的),我仍然能够在SQLiteStudio中打开和编辑数据库,而无需任何密码。直到我使用该ChangePassword方法(调用该Open方法之后),密码应用程序实际上才“卡住”。
G_Hosa_Phat


7

您可以sqlite3.dllhttp://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可以嵌入到我的可执行文件中的文件。我没有任何dll。
ahmd0 2014年

2
另请检查此github.com/rindeal/wxSQLite3-VS,它将为您提供libdll文件。
Mohammad Banisaeid 2014年

4

请记住,以下内容不能替代适当的安全解决方案。

在玩了四天之后,我只使用了NuGet的开源System.Data.SQLite程序包组合了一个解决方案。我不知道这能提供多少保护。我只是将其用于自己的学习课程。这将创建数据库,对其进行加密,创建表并添加数据。

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

2

您始终可以在客户端上加密数据。请注意,由于性能问题,并非所有数据都必须加密。


1

好吧,SEE很贵。但是SQLite具有内置的加密接口(Pager)。这意味着,不必在现有代码之上轻松开发某种加密机制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,但需要使用PHPSQLite扩展进行编译。它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');
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.