Muh*_*eem 5 android sqlcipher-android android-room
我的应用程序目前正在使用房间数据库。我想迁移到使用 Sqlcipher 数据库。我已经fallbackToDestructiveMigration()启用但仍然抛出以下错误
java.lang.RuntimeException: Exception while computing database live data.
at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:92)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: net.sqlcipher.database.SQLiteException: file is not a database: , while compiling: select count(*) from sqlite_master;
at net.sqlcipher.database.SQLiteCompiledSql.native_compile(Native Method)
at net.sqlcipher.database.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
at net.sqlcipher.database.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
at net.sqlcipher.database.SQLiteProgram.<init>(SQLiteProgram.java:91)
at net.sqlcipher.database.SQLiteQuery.<init>(SQLiteQuery.java:48)
at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:60)
at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:2016)
at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1902)
at net.sqlcipher.database.SQLiteDatabase.keyDatabase(SQLiteDatabase.java:2673)
at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2603)
at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1247)
at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1322)
at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:166)
at net.sqlcipher.database.SupportHelper.getWritableDatabase(SupportHelper.java:83)
at androidx.room.RoomDatabase.inTransaction(RoomDatabase.java:476)
at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.java:281)
at androidx.room.RoomDatabase.query(RoomDatabase.java:324)
at androidx.room.util.DBUtil.query(DBUtil.java:83)
at com.screenlocker.secure.room.MyDao_Impl$29.call(MyDao_Impl.java:1249)
at com.screenlocker.secure.room.MyDao_Impl$29.call(MyDao_Impl.java:1246)
at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:90)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Run Code Online (Sandbox Code Playgroud)
有没有办法销毁我所有的数据库并转移到 Sqlcipher?我也尝试过database.delete("table_name",null,null)手动删除表和迁移的命令,但它仍然无法正常工作。我的数据库创建代码如下。
DatabaseSecretProvider provider = new DatabaseSecretProvider(context);
byte[] passphrase = provider.getOrCreateDatabaseSecret().asBytes();
SupportFactory factory = new SupportFactory(passphrase);
instance = Room.databaseBuilder(context, MyAppDatabase.class, AppConstants.DATABASE_NAME)
.openHelperFactory(factory)
.fallbackToDestructiveMigration()
.build();
Run Code Online (Sandbox Code Playgroud)
我正在使用以下版本的 Sqlcipher
implementation 'net.zetetic:android-database-sqlcipher:4.3.0'
implementation "androidx.sqlite:sqlite:2.1.0"
Run Code Online (Sandbox Code Playgroud)
小智 6
您可以使用 sqlcipher 的便捷方法加密未加密的数据库sqlcipher_export。因此,您不必使用fallbackToDestructiveMigration或花时间编写自定义迁移工具。
来自开发者的网站:
\n\n\n要使用 sqlcipher_export() 加密现有数据库,首先打开标准 SQLite 数据库,但不要\xe2\x80\x99t 提供密钥。接下来,附加一个新的加密数据库,然后在 SELECT 语句中调用 sqlcipher_export() 函数,传入要写入主数据库架构和数据的附加数据库的名称。
\n
$ ./sqlcipher plaintext.db\nsqlite> ATTACH DATABASE \'encrypted.db\' AS encrypted KEY \'newkey\';\nsqlite> SELECT sqlcipher_export(\'encrypted\');\nsqlite> DETACH DATABASE encrypted;\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n最后,安全地删除现有的明文数据库,然后像往常一样使用 sqlite3_key 或 PRAGMA 密钥打开新的加密数据库。
\n
@commonsguy还有一个如何在 Android 中执行此操作的示例:
\n$ ./sqlcipher plaintext.db\nsqlite> ATTACH DATABASE \'encrypted.db\' AS encrypted KEY \'newkey\';\nsqlite> SELECT sqlcipher_export(\'encrypted\');\nsqlite> DETACH DATABASE encrypted;\nRun Code Online (Sandbox Code Playgroud)\n\n您可以context.getDatabasePath(DATABASE_NAME)作为originalFile参数传递。
另外,请参阅commonsguy 的评论,它解释了如何将其与getDatabaseState函数结合使用,将数据从现有的纯文本数据库迁移到 sqlcipher 加密数据库。
这对我有用,但我觉得这不是最好的答案:
val factory: SupportFactory = SupportFactory(masterKeyAlias.toByteArray())
private fun buildDatabase(context: Context) =
Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"MyDatabaseNew.db" // <<--- change the name of this database file
).openHelperFactory(factory)
.build()
Run Code Online (Sandbox Code Playgroud)
这是一个全新的数据库,数据需要全新填充。也许有一种方法可以在迁移中迁移它。
| 归档时间: |
|
| 查看次数: |
1459 次 |
| 最近记录: |