具有加密/密码保护的 SQLite

Posted

技术标签:

【中文标题】具有加密/密码保护的 SQLite【英文标题】:SQLite with encryption/password protection 【发布时间】:2011-08-05 21:48:43 【问题描述】:

我刚刚学习使用 SQLite,我很好奇这是否可行:

    数据库文件加密?

    密码保护打开数据库?

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

【问题讨论】:

这当然是可能的,除了 SEE 之外,还有几个开源解决方案。其中 wxSQLite3 附带的加密扩展。 See my answer to a similar question for details. @RobotMess:老实说——这里没有列出。我对那个项目有严格的时间限制,所以我必须尽快做一些事情。我采用了我最了解的方法——在将原始数据放入数据库之前对原始数据进行 AES... @ahmd0 嗯,这不是让数据库有点没用吗?我的意思是,它现在真正要做的就是确保提交是原子的。 是的,这是可能的。如果针对 .Net Standard 4.6.1+ 或 Core,我认为获得 Sqlite 加密的一个相当简单的方法是按照我的回答 here 使用 Microsoft.Data.Sqlite。 【参考方案1】:

SQLite 内置了用于加密的钩子,这些钩子在正态分布中不使用,但这里有一些我知道的实现:

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

SEE 和 SQLiteCrypt 需要购买许可证。

披露:我创建了 botansqlite3。

【讨论】:

您有任何关于如何使用 Botan 进行 SQLite 数据库加密的文档吗? Botan 网站未提及此功能。 botansqlite3 现在独立于 Botan 分发。 还有litereplica。它使用 ChaCha 密码,在基于 ARMv7 的便携式设备上比 AES 更快 SQLite3 .Net 现在内置了对加密的支持,这在很大程度上使这个答案无效。 嗨我用 System.Data.Sqlite c# 创建了一个文件,它有密码,我想在 php 中使用它。你知道怎么做吗?谢谢【参考方案2】:

您可以使用密码保护 SQLite3 数据库。 首次进行任何操作前,请按如下方式设置密码。

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

【讨论】:

不适用于开源 Sqlite。不知道这应该是什么语言实现、语言或 API。 我怎么知道ChangePassword使用了哪种加密方式? AES 128? RSA ..? RSA 1024 还是 2048?是否有任何文件可以看到更多细节? 从这里获取文档system.data.sqlite.org/index.html/doc/trunk/www/index.wiki 在我自己的测试中,我发现SetPassword方法(此时)看起来基本没用。我能够让System.Data.SQLite 库正确应用密码的唯一方法是使用ChangePassword 方法。使用SetPassword之前调用Open方法,显然是库要求的),我仍然能够在没有任何密码的情况下在SQLiteStudio中打开和编辑数据库。直到我使用ChangePassword 方法(调用Open 方法之后)密码应用程序才真正“卡住”。【参考方案3】:

.net 库System.Data.SQLite 也提供加密功能。

【讨论】:

ASP.NET != SQL Server != 已安装的 SQL Server 实例 但是System.Data.SQLite 不是来自微软。这个问题与 .Net 无关,但如果是,那么其他兼容性和不兼容性将很重要。【参考方案4】:

您可以从http://system.data.sqlite.org/ 获取具有加密支持的sqlite3.dll 文件。

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。 请同时检查这个github.com/rindeal/wxSQLite3-VS,它将为您提供libdll 文件。【参考方案5】:

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

在玩了四天之后,我只使用来自 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 方法。

要解密,只需在调用 open 之前将密码放入连接字符串中即可。

        string filename = @"C:\Programming\sqlite3\db.db";
        string passwordString = "password";
        SQLiteConnection conn = new SQLiteConnection("Data Source=" + filename + ";Version=3;Password=" + passwordString + ";");
        conn.Open();

【讨论】:

"I think I saw 128 bit somewhere" - 如果您打算处理加密,这是一个非常糟糕的声明。经验法则是,如果您不了解,则永远自己做。否则你最好不要使用它。 我明白你的意思。我主要是试图纠正我看到的不适用于当前版本的 System.Data.Sqlite 的建议。我并不是要暗示这是很好的安全性。我已经更新了我的帖子。感谢您的意见! SetPassword 在 SQLiteConnection 对象中不存在,System.Data.SQLite 1.0.113.0【参考方案6】:

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

【讨论】:

【参考方案7】:

嗯,SEE 很贵。但是SQLite 具有内置的加密接口(寻呼机)。这意味着,在现有代码之上可以轻松开发一些加密机制,不必是AES。真的什么都有。 请在此处查看我的帖子:https://***.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

【讨论】:

【参考方案8】:

您可以使用 SQLite 的函数创建例程 (PHP manual):

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

插入数据时,可以直接使用加密函数,INSERT加密数据,也可以使用自定义函数,传递未加密数据:

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

【讨论】:

【参考方案9】:

我也有类似的问题。需要将敏感数据存储在简单的数据库中(SQLite 是除了安全性之外的完美选择)。最后,我将数据库文件放在 TrueCrypt 加密值上。

其他控制台应用程序使用 TrueCrypt CLI 安装临时驱动器,然后启动数据库应用程序。等待数据库应用程序退出,然后再次卸载驱动器。

也许不是在所有情况下都适合的解决方案,但对我来说工作得很好......

【讨论】:

以上是关于具有加密/密码保护的 SQLite的主要内容,如果未能解决你的问题,请参考以下文章

C# 判断 SQLite 数据库文件是不是经过密码加密

如何使用 aes 算法加密 sqlite 文件?

数据保护、钥匙串和核心数据的 Sqlite 文件

我应该如何保护 iOS 中的 SQLite 数据库?

13flask密码加密

保护本地 SQLite 数据库(Android 应用程序)