Android Sqlchipher:net.sqlcipher.database.SQLiteException:文件已加密或不是数据库

时间:2013-12-16 15:07:14

标签: android encryption sqlcipher

我使用Sqlcipher进行数据库加密。我正在使用 SQLiteDatabase.openDatabase 来创建,编辑和读取sqlchiphered数据库。我可以正常打开,阅读和编​​辑,但突然间我得到了以下错误,之后我无法打开数据库本身

12-25 17:59:07.961: E/Database(6794): SELECT locale FROM android_metadata failed
12-25 17:59:07.961: W/System.err(6794): net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
12-25 17:59:07.966: W/System.err(6794):     at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
12-25 17:59:07.966: W/System.err(6794):     at net.sqlcipher.database.SQLiteDatabase.setLocale(Unknown Source)
12-25 17:59:07.966: W/System.err(6794):     at net.sqlcipher.database.SQLiteDatabase.<init>(Unknown Source)
12-25 17:59:07.966: W/System.err(6794):     at net.sqlcipher.database.SQLiteDatabase.<init>(Unknown Source)

我已经检查了问题,但我无法得到任何有用的信息。所以帮助我解决这个问题

注意:

我已经更新了我的sqlcipher并将应用程序作为一个新的应用程序运行(不是对我以前的应用程序的更新),它只是正确的但是突然之间我得到了上述错误而且我根本无法打开我的数据库(直到我清除数据应用程序管理器中的应用程序)

目前我正在使用2.2版本的SQLCipher

先谢谢

2 个答案:

答案 0 :(得分:1)

同样的事情发生在我身上,这是因为在更新SQLCipher库之后,我还需要将数据库从我使用的版本1.1.x升级到2.2.2。见here为什么。为此,您需要使用SQLiteDatabase.upgradeDatabaseFormatFromVersion1To2(File dbPath, String key)。问题是此方法不保留db版本,因此我们需要手动执行此操作。所以代码将是这样的:

 //Open the old formatted db with cipher_use_hmac = OFF;
 SQLiteDatabaseHook hook = new SQLiteDatabaseHook() {

     public void preKey(SQLiteDatabase database) {}

     public void postKey(SQLiteDatabase database) {
         database.rawExecSQL("PRAGMA cipher_use_hmac = OFF;");
     }
 };

 //Read the db version
 SQLiteDatabase old_db = SQLiteDatabase.openOrCreateDatabase(path, mPassword, mFactory, hook);
 int version = old_db.getVersion();
 old_db.close();

 //Do the upgrade to 2.x format
 try {
     SQLiteDatabase.upgradeDatabaseFormatFromVersion1To2(new File(path), mPassword);
 } catch (Exception e) {
     e.printStackTrace();
 }

//Manually set the db version to the updated db.
SQLiteDatabase updated_db = SQLiteDatabase.openOrCreateDatabase(path, mPassword, mFactory);
updated_db.setVersion(version);

以上代码将永久更新SQLCipher数据库格式为2.2.2版本。如果要更新为新的3.x格式,则流程会有所不同,您需要使用PRAGMA cipher_migrate方法(请参阅here)。我避免使用3.x格式,因为默认的KDF迭代计数是64000(从4000开始),这使得数据库的读数/写入速度非常慢。 2.2.2版本与KitKat兼容。

答案 1 :(得分:0)

从您之前的评论中,您已将SQLCipher for Android从先前版本升级到最新版本,这是正确的吗?如果是这样,您之前运行的是哪个版本以及您现在运行的是哪个版本?您是否能够访问您的数据库,或者您是否始终看到此问题。您可以考虑将此问题移至SQLCipher Mailing List,因为通过电子邮件进行诊断可能更容易。