使用SQLCipher -Android将纯内容提供程序数据(由SQLite支持)升级为加密的 [英] Upgrading plain content provider data(backed by SQLite) to encrypted using SQLCipher -Android
问题描述
我正在尝试通过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屋!