SQLCipher で DBFlow を使用しています。AndroidでSQLCipherを使用して、既存のSQLiteデータベース(DBFlowを使用)を暗号化しようとしています。
次のコードを使用して DB を暗号化しました。
private void encryptDB() {
SQLiteDatabase.loadLibs(this);
String password = "test123";
String LEGACY_DATABASE_NAME = "legacy.db";
String NEW_DATABASE_NAME = "new_crypt.db";
File newDBFile = getDatabasePath(NEW_DATABASE_NAME);
File legacyFile = getDatabasePath(LEGACY_DATABASE_NAME);
if (!newDBFile.exists() && legacyFile.exists()) {
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(legacyFile, "", null);
db.rawExecSQL(String.format("ATTACH DATABASE '%s' AS encrypted KEY '%s';", newDBFile.getAbsolutePath(), password));
db.rawExecSQL("SELECT sqlcipher_export('encrypted')");
db.rawExecSQL("DETACH DATABASE encrypted;");
db.close();
db = SQLiteDatabase.openDatabase(newDBFile.getAbsolutePath(), password, null, SQLiteDatabase.OPEN_READWRITE);
db.close();
legacyFile.delete();
newDBFile.renameTo(legacyFile);
}
}
DB は問題なく暗号化されていますが、操作を書き込もうとすると、次のようになります。
Place place = new Place();
place.setName("Test");
place.save();
DB モデル:
@Table(database = DatabaseManager.class)
public class Place extends BaseModel {
@Column
String name;
// set and get methods goes here
}
次に、次の例外を取得します。
io.reactivex.exceptions.UndeliverableException: android.database.sqlite.SQLiteReadOnlyDatabaseException: 読み取り専用データベースを書き込もうとしています (コード 1032 SQLITE_READONLY_DBMOVED[1032])
ここで同様の投稿を見つけましたが、解決策は見つかりませんでした。
また、DBFlow データベースを SQLCipher で暗号化する方法を発見し、実装しました。その後、新しいアプリとしてインストールすると機能しますが、DB を暗号化していない古いアプリの上にこのアプリをインストールすると失敗します。
net.sqlcipher.database.SQLiteException: ファイルはデータベースではありません: 、コンパイル中: select count(*) from sqlite_master;
どうすればこれを修正できますか?