加密/解密现有的数据库在Android中使用SQLCipher数据库、Android、SQLCipher

2023-09-05 09:56:03 作者:青春为你更新

我用下面的一块code加密和数据库我能够进行加密解密,但是当我试图解密,我发现了以下exception.I提到这个的文档和的的TestCase 中也依然面临着同样的问题。

例外:

 源码返回:错误code = 26,味精=文件加密或不是一个数据库
CREATE TABLE android_metadata失败
失败的setLocale()施工时,关闭数据库
net.sqlcipher.database.SQLiteException:文件是加密的或不是一个数据库
 

加密:

 私有静态无效ConvertNormalToSQLCipheredDB(上下文的背景下,
 字符串startingFileName,字符串endingFileName,字符串filePassword)
 抛出IOException异常{
  文件mStartingFile = context.getDatabasePath(startingFileName);
  如果(!mStartingFile.exists()){
   返回;
  }
  文件mEndingFile = context.getDatabasePath(endingFileName);
  mEndingFile.delete();
  SQLiteDatabase数据库= NULL;
  尝试 {
   数据库= SQLiteDatabase.openOrCreateDatabase(MainApp.mainDBPath,
   , 空值);
   database.rawExecSQL(的String.Format(
   附加数据库%s,因为加密的密钥'%s'的,
   mEndingFile.getAbsolutePath(),filePassword));
   database.rawExecSQL(选择sqlcipher_export('加密'));
   database.rawExecSQL(分离数据库加密);
   database.close();
  }赶上(例外五){
   e.printStackTrace();
  } 最后 {
   如果(database.isOpen())
    database.close();
   mStartingFile.delete();
  }
 }
 

解密:

 私人无效decryptDatabase(){
  文件unencryptedFile = getDatabasePath(PhoneNumbersDatabase.DATABASE_NAME);
  unencryptedFile.delete();
  文件databaseFile = getDatabasePath(encrypt.db);
  SQLiteDatabaseHook挂钩=新SQLiteDatabaseHook(){
   公共无效pre键(SQLiteDatabase sqLiteDatabase){
    sqLiteDatabase
      .rawExecSQL(杂cipher_default_use_hmac =关闭;);
   }

   公共无效postKey(SQLiteDatabase sqLiteDatabase){
   }
  };
  SQLiteDatabase数据库= SQLiteDatabase.openOrCreateDatabase(
    databaseFile,test123,空,钩); // 例外
  如果(database.isOpen()){
   database.rawExecSQL(的String.Format(
     附加数据库%s的明文键'';,
     unencryptedFile.getAbsolutePath()));
   database.rawExecSQL(选择sqlcipher_export('明文'););
   database.rawExecSQL(分离数据库明文;);
   android.database.sqlite.SQLiteDatabase SQLDB = android.database.sqlite.SQLiteDatabase
     .openOrCreateDatabase(unencryptedFile,NULL);
   sqlDB.close();
   database.close();
  }

  databaseFile.delete();
 }
 
android studio sqlite调用就闪退 使用VS编译SQLite数据库及如何在C 中使用加密数据库SQLCipher...

解决方案

您不需要设置 cipher_default_use_hmac 关闭 pre键事件当您尝试数据库解密。当你这样加密的HMAC被列入数据库的每一页的数据库没有被禁用。尝试从解密功能删除您 SQLiteDatabaseHook 。另外,还要考虑这些类型的讨论加入 SQLCipher通讯录。

I'm using the below piece of code to encrypt and decrypt the database i'm able to encrypt but when i'm trying to decrypt i'm getting the below exception.I referred this documentation and TestCases too still facing the same problem.

Exception:

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

Encrypt:

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();
  }
 }

Decrypt:

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();
 }

解决方案

You do not need to set cipher_default_use_hmac to off in the preKey event when you attempt to decrypt the database. It is not being disabled when you encrypt the database so an HMAC is being included for every page of the database. Try removing your SQLiteDatabaseHook from the decryption function. Also, consider joining the SQLCipher Mailing List for these type of discussions.