无法将sqlcipher加密数据库附加到另一个

时间:2013-11-02 13:42:09

标签: database sqlite encryption sqlcipher

我正在使用一个使用由sqlcipher加密的数据库的应用。此加密的密码由cacheword存储。

为了备份我的数据库,我使用了以下代码:

// ggf. Datenbank öffnen
openGuard();
mDb.execSQL("ATTACH DATABASE '" + outFileName + "' AS backup KEY 'asdfghjkl';");
mDb.rawExecSQL("SELECT sqlcipher_export('backup');");
mDb.execSQL("DETACH DATABASE backup;");

方法openGuard()用于检查数据库是否已打开,如果不是,则执行此操作。

我已使用空密钥检查备份,以生成数据库的未加密副本。然后我可以在adb shell上使用它并使用sql-statements来获取想要的数据。

我的问题很长一段时间是我无法使用我的备份来恢复我的应用程序的数据库。我试过这段代码:

SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(backupFile, "asdfghjkl", null);
db.execSQL("ATTACH DATABASE '" + dbFile + "' AS encrypted KEY '" + mCacheWord.getEncryptionKey() + "';");
db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
db.rawExecSQL("DETACH DATABASE encrypted;");

或者我试过

db.execSQL("ATTACH DATABASE '" + dbFile + "' AS encrypted KEY '" + encodeRawKey(mCacheWord.getEncryptionKey()) + "';");

但是在这两种情况下我都收到以下错误消息:

10-30 00:56:42.845: I/Database(14407): sqlite returned: error code = 26, msg = statement aborts at 5: [ATTACH DATABASE '/data/data/.../databases/database.db' AS encrypted KEY '[B@42082da0';] file is encrypted or is not a database
10-30 00:56:42.845: E/Database(14407): Failure 26 (file is encrypted or is not a database) on 0x63bdedb0 when executing 'ATTACH DATABASE '/data/data/.../databases/database.db' AS encrypted KEY '[B@42082da0';'

有没有人可以帮我解决我的问题?

2 个答案:

答案 0 :(得分:0)

通过 ATTACH DATABASE 语句提供密钥,您似乎意外“挂断”试图解密。查看API的 Example 2: Decrypt a SQLCipher database to a Plaintext Database ,评论内容为 -- empty key will disable encryption 。因此,大概您的初始解密代码尝试应首先执行 PRAGMA key = 语句(提供密钥),然后执行 ATTACH DATABASE 语句用空键(解密)这样的东西:

db.execSQL("PRAGMA key = '" + mCacheWord.getEncryptionKey() + "';");
db.execSQL("ATTACH DATABASE '" + dbFile + "' AS encrypted KEY '';");
db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
db.rawExecSQL("DETACH DATABASE encrypted;");

有关此问题的另一个简短示例可以在 the SQLCipher Users mailing list 讨论中看到。

答案 1 :(得分:0)

我认为问题可能与您使用CacheWord有关,后者与SQLCipher分开管理加密密钥。您应该验证从getEncryptionKey()返回的字符串的格式,并确保它与SQLCIpher中原始键的正确格式匹配。