加密SQLite
我将编写自己的加密,但希望讨论一些内部内容。应在多个移动平台上使用-iOS、Android、WP7,桌面或多或少用作测试平台 让我们首先从现有解决方案的简要特征开始:加密SQLite,sqlite,Sqlite,我将编写自己的加密,但希望讨论一些内部内容。应在多个移动平台上使用-iOS、Android、WP7,桌面或多或少用作测试平台 让我们首先从现有解决方案的简要特征开始: SQLite标准(商业)见扩展-我不知道它在内部是如何工作的,也不知道它是如何与上述移动平台合作的 System.data.sqlite(仅限Windows):完整数据库的RC4选项,ECB模式。它们还加密数据库头,这偶尔(0.01%的几率)会导致数据库损坏。*)另外的优势:它们使用SQLite合并分发 SqlCipher(op
- SQLite标准(商业)见扩展-我不知道它在内部是如何工作的,也不知道它是如何与上述移动平台合作的
- System.data.sqlite(仅限Windows):完整数据库的RC4选项,ECB模式。它们还加密数据库头,这偶尔(0.01%的几率)会导致数据库损坏。*)另外的优势:它们使用SQLite合并分发
- SqlCipher(openssl,即多个平台):可选择的加密方案。他们加密整个数据库。CBC模式(我想),随机IV向量。因此,他们必须修改页面参数(大小+存储IV的保留空间)。他们意识到与未加密读取DB头相关的问题,并尝试引入解决方法,但解决方案并不令人满意。其他缺点:它们使用SQLite3源代码树。(另一方面,它支持其他功能,即使用特殊杂注微调加密参数。)
- 加密除DB头之外的整个DB
- ECB模式:听起来很危险,但在简要查看了DB格式后,我无法想象如何利用它进行攻击李>
- AES128
- SQLite合并之上的实现(类似于system.data.SQLite)
已编辑-基于VFS的加密案例 上述方法使用sqlite.org认可的基于编解码器的方法。这是一组3个回调,其中最重要的是:
void *(*xCodec)(void *iCtx, void *data, Pgno pgno, int mode)
此回调由SQLite自行决定用于加密/解密从磁盘读取/写入的数据。数据逐页交换。(页是512乘的倍数。)
另一种选择是使用VFS。VFS是一组用于低级操作系统服务的回调。其中有几个与文件相关的服务,例如xOpen/xSeek/xRead/xWrite/xClose。特别是,以下是用于数据交换的方法
int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst);
这些调用中的数据大小从4by(常见情况)到DB页面大小不等。如果您想使用块密码(还需要使用什么?),那么您需要组织底层块缓存。我无法想象一个实现会像SQLite内置事务一样安全和高效
第二个问题:VFS实现依赖于平台。Android/iOS/WP7/desktop都使用不同的源,即基于VFS的加密必须逐平台实施
下一个问题更微妙:平台可能使用VFS调用来实现文件锁定。不得对这些用途进行加密。此外,共享锁不能被缓冲。换句话说,VFS级别的加密可能会破坏锁定功能
基于VFS加密的编辑明文攻击 我后来意识到了这一点:DB头以固定字符串“SQLite format 3”开头,头包含许多其他固定字节值。这为已知的明文攻击(KPA)打开了大门 这主要是基于VFS的加密的问题,因为它没有正在加密DB头的信息 System.data.sqlite也有这个问题,因为它同时加密(RC4)DB头
SqlCipher使用用于将密码转换为密钥的salt覆盖hdr字符串。此外,它默认使用AES,因此KPA攻击没有危险。您不需要攻击db格式或sqlite源代码。SQLite公开了虚拟文件系统(vfs)API,该API可用于使用加密层包装文件系统(或另一个vfs),加密层可动态加密/解密页面。当我这么做的时候,结果证明这是一项非常简单的任务,大约只有几百行代码。这样整个数据库将被加密,包括日志文件,它对任何客户端代码都是完全透明的。对于1024的典型页面大小,几乎可以使用任何已知的分组密码。从他们的文档中我可以得出结论,这正是SQLCipher所做的 关于您看到的“问题”:
- 您不需要重新实现文件系统支持,您可以绕过默认的VFS。因此,锁或平台依赖性没有问题
- SQLite的默认操作系统后端也是VFS,使用VFS没有任何开销,只需添加
- 您不需要块缓存。当然,当它只需要4个字节时,您必须读取整个块,但不要缓存它,它将永远不会被再次读取。SQLite有自己的缓存来防止这种情况(寻呼机模块)
- 自身加密(AES128),CBC模式
- 编解码器接口(与SqlCipher或system.data.sqlite使用的相同)
- 数据库头未加密
- 页面标题也未加密,用于IV生成
- 使用合并SQLite分布
- 没有得到太多回应,所以我的决定如下:
AFAIK此解决方案应该比SqlCipher或system.data.sqlite更好。在您提到的每个平台上,是否都没有可以使用的现有加密系统?他们说“自己滚”加密可能有风险,因为你可能会引入安全问题,而这些问题会在一个好的预制库中被检测到。是的,每个平台都提供各种加密方案。但我还需要加密方案和密钥生成的二进制兼容性。这需要一个