【发布时间】:2017-01-22 13:51:30
【问题描述】:
我的资产中有一个数据库文件,我将其复制到应用程序数据库文件夹中。复制后(有效),我想用 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
如果我用根资源管理器查看数据库,它仍然没有加密且可见,所以我认为错误与 encrypt 方法中的文件逻辑有关。
这是我创建的 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());
}
}
}
}
【问题讨论】:
标签: android database encryption android-file sqlcipher