2014-01-07 124 views
2

我使用下面的一段代碼來加密和解密數據庫,我可以加密但是當我試圖解密時,我得到了下面的異常。提到這個documentationTestCases也仍然面臨同樣的問題。在Android中使用SQLCipher加密/解密現有數據庫

例外:

sqlite returned: error code = 26, msg = file is encrypted or is not a database 
CREATE TABLE android_metadata failed 
Failed to setLocale() when constructing, closing the database 
net.sqlcipher.database.SQLiteException: file is encrypted or is not a database 

加密:

private static void ConvertNormalToSQLCipheredDB(Context context, 
String startingFileName, String endingFileName, String filePassword) 
throws IOException { 
    File mStartingFile = context.getDatabasePath(startingFileName); 
    if (!mStartingFile.exists()) { 
    return; 
    } 
    File mEndingFile = context.getDatabasePath(endingFileName); 
    mEndingFile.delete(); 
    SQLiteDatabase database = null; 
    try { 
    database = SQLiteDatabase.openOrCreateDatabase(MainApp.mainDBPath, 
    "", null); 
    database.rawExecSQL(String.format(
    "ATTACH DATABASE '%s' AS encrypted KEY '%s'", 
    mEndingFile.getAbsolutePath(), filePassword)); 
    database.rawExecSQL("select sqlcipher_export('encrypted')"); 
    database.rawExecSQL("DETACH DATABASE encrypted"); 
    database.close(); 
    } catch (Exception e) { 
    e.printStackTrace(); 
    } finally { 
    if (database.isOpen()) 
    database.close(); 
    mStartingFile.delete(); 
    } 
} 

解密:

private void decryptDatabase() { 
    File unencryptedFile = getDatabasePath(PhoneNumbersDatabase.DATABASE_NAME); 
    unencryptedFile.delete(); 
    File databaseFile = getDatabasePath("encrypt.db"); 
    SQLiteDatabaseHook hook = new SQLiteDatabaseHook() { 
    public void preKey(SQLiteDatabase sqLiteDatabase) { 
    sqLiteDatabase 
     .rawExecSQL("PRAGMA cipher_default_use_hmac = off;"); 
    } 

    public void postKey(SQLiteDatabase sqLiteDatabase) { 
    } 
    }; 
    SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(
    databaseFile, "test123", null, hook); // Exception 
    if (database.isOpen()) { 
    database.rawExecSQL(String.format(
    "ATTACH DATABASE '%s' as plaintext KEY '';", 
    unencryptedFile.getAbsolutePath())); 
    database.rawExecSQL("SELECT sqlcipher_export('plaintext');"); 
    database.rawExecSQL("DETACH DATABASE plaintext;"); 
    android.database.sqlite.SQLiteDatabase sqlDB = android.database.sqlite.SQLiteDatabase 
    .openOrCreateDatabase(unencryptedFile, null); 
    sqlDB.close(); 
    database.close(); 
    } 

    databaseFile.delete(); 
} 
+0

看看這些樣品。這些是自我解釋:https://github.com/sqlcipher/android-database-sqlcipher/tree/master/dist/SQLCipherForAndroid-SDK/samples/basic/example – Tobrun

+0

當我使用像你的加密方法我面臨一個異常說:數據庫被鎖定!你能幫我解答嗎? –

回答

4

設置你不需要到offpreKey事件當您嘗試解密數據庫。當您加密數據庫時,它不會被禁用,因此每個數據庫頁面都包含一個HMAC。嘗試從解密功能中刪除您的SQLiteDatabaseHook。另外,考慮加入SQLCipher Mailing List進行這類討論。

+0

謝謝你回覆尼克...不知何故,我能弄明白...我會接受這個答案的解釋。 –

相關問題