我的资产中有一个数据库文件,我将其复制到app数据库文件夹中。复制(它工作)后,我想用SQLCipher加密复制的数据库。
出于某种原因,我收到了这个错误:
Database: sqlite returned: error code = 26, msg = statement aborts at 5: [ATTACH DATABASE '/data/user/0/com.grandeguru.lagmeup/databases/AIRPORTS_DB.db' AS encrypted KEY 'password';] file is encrypted or is not a database
如果我使用根浏览器查看数据库,它仍然没有加密和可见,所以我认为错误与加密方法中的文件逻辑有关。
这是我创建的DatabaseHelper类的代码,它还管理资产中的副本:
public class DatabaseHelper extends SQLiteOpenHelper {
private SQLiteDatabase myDB;
private Context context;
public static String DB_NAME = "AIRPORTS_DB.db";
public static String DB_PATH = "/data/data/com.grandeguru.lagmeup/databases/";
public static final int DB_VERSION = 1;
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
myDB.loadLibs(context);
this.context = context;
}
// THE ERROR IS SOMEWHERE INSIDE HERE
public void encryptDataBase(String passphrase) throws IOException {
File originalFile = context.getDatabasePath(DB_NAME);
File newFile = File.createTempFile("sqlcipherutils", "tmp", context.getCacheDir());
openDataBase("");
myDB.rawExecSQL("ATTACH DATABASE '" + originalFile.getPath() + "' AS encrypted KEY '" + passphrase + "';");
myDB.rawExecSQL("SELECT sqlcipher_export('encrypted');");
myDB.rawExecSQL("DETACH DATABASE encrypted;");
myDB.close();
myDB = SQLiteDatabase.openDatabase(newFile.getAbsolutePath(), passphrase, null, SQLiteDatabase.OPEN_READWRITE);
myDB.close();
newFile.renameTo(originalFile);
originalFile.delete();
}
private boolean checkDataBase() {
File databasePath = context.getDatabasePath(DB_NAME);
return databasePath.exists();
}
public void copyDataBase() throws IOException {
try {
File f = context.getDatabasePath(DB_NAME);
InputStream in = context.getAssets().open(DB_NAME);
OutputStream out = new FileOutputStream(f.getAbsolutePath());
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
out.flush();
out.close();
in.close();
Log.d("copy database", "finita copia db");
encryptDataBase("password");
} catch (Exception e) {
Log.e("copy database", e.getMessage());
}
}
public void openDataBase(String passphrase) throws SQLException {
String myPath = DB_PATH + DB_NAME;
myDB = SQLiteDatabase.openDatabase(myPath, passphrase, null, SQLiteDatabase.OPEN_READWRITE);
}
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
} else {
this.getReadableDatabase("");
try {
copyDataBase();
} catch (IOException e) {
Log.e("create database", e.getMessage());
}
}
}
}
答案 0 :(得分:3)
我解决了,我把我的解决方案作为未来的参考。我只是走错了道路
public void encryptDataBase(String passphrase) throws IOException {
File originalFile = context.getDatabasePath(DB_NAME);
File newFile = File.createTempFile("sqlcipherutils", "tmp", context.getCacheDir());
SQLiteDatabase existing_db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, "", null, SQLiteDatabase.OPEN_READWRITE);
existing_db.rawExecSQL("ATTACH DATABASE '" + newFile.getPath() + "' AS encrypted KEY '" + passphrase + "';");
existing_db.rawExecSQL("SELECT sqlcipher_export('encrypted');");
existing_db.rawExecSQL("DETACH DATABASE encrypted;");
existing_db.close();
originalFile.delete();
newFile.renameTo(originalFile);
}
答案 1 :(得分:0)
我们有一个在SQLCipher for Android test suite here内加密纯文本SQLite数据库的示例。此外,您可以尝试调用静态SQLiteDatabase.loadLibs(context);
,而不是尝试在实例字段上调用它。