1

sqlcipher_export()完全按照此处指定的方式使用来加密现有的 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日志在这里

(如果我编译 Sqlcipher 的方式很重要:我在 Linux 机器上创建了一个 Sqlcipher 合并,将生成的 C 文件复制到 Windows 机器,在 Visual C++ Express 中编译它,并链接到预编译的 OpenSSL DLL。)

4

1 回答 1

0

HMAC_Init_ex()根本原因:在sqlcipher_page_hmac()属于的损坏内存中调用 OpenSSL c_ctx->key_sz,将其设置为零。c_ctx->key_sz与传递给的参数相邻HMAC_Init_ex()。(详细信息可以在原始帖子的评论之一中找到。)这导致sqlcipher_page_cipher()将纯文本页面写入加密文件,而不是加密页面。这没有任何意义,并使生成的数据库无法使用。

将 OpenSSL 从 0.9.8k 升级到 1.0.0i 解决了这个问题。

于 2012-04-21T09:42:00.153 回答