加密/解密现有的数据库在Android中使用SQLCipher [英] Encrypt/Decrypt existing database using SQLCipher in Android

查看:979
本文介绍了加密/解密现有的数据库在Android中使用SQLCipher的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用下面的一块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();
 }
 

解决方案

您不需要设置 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.

这篇关于加密/解密现有的数据库在Android中使用SQLCipher的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆