使用SQLCipher -Android将纯内容提供程序数据(由SQLite支持)升级为加密的 [英] Upgrading plain content provider data(backed by SQLite) to encrypted using SQLCipher -Android

查看:239
本文介绍了使用SQLCipher -Android将纯内容提供程序数据(由SQLite支持)升级为加密的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过App升级对存储在内容提供商中的数据进行加密.我点击了以下链接,
如何在使用SQLiteOpenHelper时实现SQLCipher

I am trying to encrypt data stored in my content provider with App upgrade. I followed below link for this,
How to implement SQLCipher when using SQLiteOpenHelper

虽然在完成新安装后可以正常工作,但是如果我进行升级,则应用程序崩溃并出现以下错误

While this works perfectly fine if a new installation is done, If I go for an upgrade, app crashes with below error

    net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
at  android.app.ActivityThread.handleReceiver(ActivityThread.java:3009)
at  android.app.ActivityThread.access$1800(ActivityThread.java:177)
at  android.app.ActivityThread$H.handleMessage(ActivityThread.java:1526)
at  android.os.Handler.dispatchMessage(Handler.java:102)
at  android.os.Looper.loop(Looper.java:145)
at  android.app.ActivityThread.main(ActivityThread.java:5951)
at  java.lang.reflect.Method.invoke(Native Method)
at  java.lang.reflect.Method.invoke(Method.java:372)
at  com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
at  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
    Caused by: net.sqlcipher.database.SQLiteException: file is encrypted or is not a database


我什至试图删除现有表并创建一个新表,只是为了看看这是否解决了问题,但这也没有帮助.请提出解决方法,我的助手"类如下,


I even tried to delete the existing tables and create a new table just to see if this solved the problem but no that was of no help either. Please suggest how to fix this, My Helper class is as below,

                public class MyDBHelper extends SQLiteOpenHelper {
                public MyDBHelper(Context context) {
                    super(context, DATABASE_NAME, null, DATABASE_VERSION);
                    SQLiteDatabase.loadLibs(context);
                }
                public static final String DATABASE_NAME = "mydb.db";

                private static final int DATABASE_VERSION = 2; // before attempting encryption it was 1

                @Override
                public void onCreate(SQLiteDatabase db) {
                    createTables(db);
                }

                @Override
                public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                    db.execSQL("DROP TABLE IF EXISTS " + "TEST_TABLE");
                    createTables(db);
                }

                private void createTables(SQLiteDatabase db){
                    db.execSQL(MyDBQueries.CREATE_TEST_TABLE);
                }
            }


我更新的提供程序现在只需使用密钥即可打开数据库,如下所示,


My updated provider simply uses a key now to open the db as below,

                SQLiteDatabase db = databaseHelper.getWritableDatabase("encryptionKey");


如前所述,全新安装效果很好,但升级会使应用程序崩溃.请提出解决方法.


As I mentioned, fresh installs works good, but upgrade crashes the app. Please suggest how to fix this.

推荐答案

数据库最初未加密,我希望通过应用升级对其进行加密

Database is not encrypted initially, I want that to be encrypted with app upgrade

这不会自动发生,并且不能作为SQLiteOpenHelper及其onUpgrade()路径的一部分发生(因为在调用onUpgrade()时,SQLiteOpenHelper将已经尝试打开未加密的数据库,但您所显示的例外会失败).

That is not going to happen automatically, and it cannot happen as part of SQLiteOpenHelper and its onUpgrade() path (as by the time onUpgrade() is called, SQLiteOpenHelper will have already attempted to open the unencrypted database, which will fail with the exception that you have shown).

您将需要单独加密该数据库.这段代码是我用过的:

You will need to separately encrypt that database. This code is what I have used:

public static void encrypt(Context ctxt, String dbName,
                             String passphrase) throws IOException {
    File originalFile=ctxt.getDatabasePath(dbName);

    if (originalFile.exists()) {
      File newFile=
          File.createTempFile("sqlcipherutils", "tmp",
                              ctxt.getCacheDir());
      SQLiteDatabase db=
          SQLiteDatabase.openDatabase(originalFile.getAbsolutePath(),
                                      "", null,
                                      SQLiteDatabase.OPEN_READWRITE);

      db.rawExecSQL(String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s';",
                                  newFile.getAbsolutePath(), passphrase));
      db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
      db.rawExecSQL("DETACH DATABASE encrypted;");

      int version=db.getVersion();

      db.close();

      db=
          SQLiteDatabase.openDatabase(newFile.getAbsolutePath(),
                                      passphrase, null,
                                      SQLiteDatabase.OPEN_READWRITE);
      db.setVersion(version);
      db.close();

      originalFile.delete();
      newFile.renameTo(originalFile);
    }
  }

encrypt()返回后,您可以继续尝试打开数据库.

After encrypt() returns, then you can go ahead and try to open the database.

这篇关于使用SQLCipher -Android将纯内容提供程序数据(由SQLite支持)升级为加密的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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