我正尝试使用App升级来加密存储在我的内容提供商中的数据。 我按照下面的链接为此, 如何在使用SQLiteOpenHelper时实现SQLCipher
虽然这完全正常,如果新安装完成,如果我去升级,应用程序崩溃与下面的错误
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我甚至试图删除现有的表格并创建一个新表格,以查看这是否解决了问题,但没有任何帮助。 请建议如何解决这个问题,我的助手类如下所示,
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); } }我更新的提供程序现在只使用一个键来打开db,如下所示,
SQLiteDatabase db = databaseHelper.getWritableDatabase("encryptionKey");正如我所提到的,全新安装效果不错,但升级会使应用程序崩溃。 请建议如何解决这个问题。
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 databaseI 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.
最满意答案
数据库最初未加密,我希望通过应用升级加密
这不会自动发生,并且它不会作为SQLiteOpenHelper及其onUpgrade()路径的一部分发生(就像onUpgrade()被调用时一样), SQLiteOpenHelper已经尝试打开未加密的数据库,这将会失败并显示异常你已经显示)。
您将需要分别加密该数据库。 这段代码是我用过的:
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()返回后,你可以继续尝试打开数据库。
Database is not encrypted initially, I want that to be encrypted with app upgrade
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); } }After encrypt() returns, then you can go ahead and try to open the database.
更多推荐
发布评论