我使用sqlcipher_export()
完全按照指定的here来加密现有的Sqlite数据库。这一切都很顺利 - 没有错误,创建结果数据库并且具有合理的大小。但是,即使我使用PRAGMA key
指定了正确的密钥,我也无法打开加密数据库。未加密的数据库打开没有问题。
此外,加密数据库看起来很奇怪;标题似乎是加密的,但不是数据。请参阅http://i.stack.imgur.com/HaBpS.png,它是显示加密(左)和未加密(右)数据库之间二进制比较的图像。
在调试器中,我可以看到,在加密过程中,程序经过sqlcipher_page_cipher()
,但大部分时间(每次除了2次调用)都会执行以下子句,并且函数会提前返回:
/* just copy raw data from in to out when key size is 0
* i.e. during a rekey of a plaintext database */
if(c_ctx->key_sz == 0) {
memcpy(out, in, size);
return SQLITE_OK;
}
加密期间发出的SQL:
ATTACH DATABASE 'encrypted.db' AS encrypted KEY '12345';
SELECT sqlcipher_export('encrypted');
DETACH DATABASE encrypted;
开放时发布的SQL:
// open database
PRAGMA key = '12345';
// try to read database - "file is encrypted or not a database"
加密和解密期间生成的CODEC_TRACE日志为here。
(如果我编译Sqlcipher很重要:我在Linux机器上创建了一个Sqlcipher合并,将生成的C文件复制到Windows机器,在Visual C ++ Express中编译,并链接到预编译的OpenSSL DLL。)
答案 0 :(得分:0)
根本原因:在属于HMAC_Init_ex()
的{{1}}已损坏内存中调用OpenSSL sqlcipher_page_hmac()
,将其设置为零。 c_ctx->key_sz
与传递给c_ctx->key_sz
的参数相邻。 (详细信息可以在原始帖子的其中一条评论中找到。)这导致HMAC_Init_ex()
将明文页面写入加密文件,而不是加密页面。这没有任何意义,并使得结果数据库无法使用。
将OpenSSL从0.9.8k升级到1.0.0i解决了这个问题。