android - 在 Android 中使用 SQLCipher 加密现有数据库

标签 android database encryption android-file sqlcipher

我的 Assets 中有一个数据库文件,我将其复制到应用程序数据库文件夹中。复制后(有效),我想用 SQLCipher 加密复制的数据库。

出于某种原因,我收到此错误:

数据库:sqlite 返回:错误代码 = 26,msg = 语句在 5 处中止:[ATTACH DATABASE '/data/user/0/com.grandeguru.lagmeup/databases/AIRPORTS_DB.db' AS encrypted KEY ' password';]文件已加密或不是数据库

如果我用根资源管理器查看数据库,它仍然没有加密并且可见,所以我认为错误与加密方法中的文件逻辑有关。

这是我创建的 DatabaseHelper 类的代码,它还管理来自 Assets 的副本:

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());
        }
    }
}

最佳答案

我解决了,我把我的解决方案写下来作为 future 的引用。我只是走错了路

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);

}

关于android - 在 Android 中使用 SQLCipher 加密现有数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39495820/

相关文章:

Android 位置管理器在调用时使应用程序崩溃

Android Checkbox - 控制 EditText?

android - 如何制作适合另一个 View 的自定义 Android 字符串选择器?

Android 自定义适配器 - 不会返回 View ?

xml - JAXB 和 JPA 将数据保存在数据库中

php - MYSQL 在不同的表中插入相同的值 PHP

encryption - 加密算法的抗冲突性如何?

android - 将 Android POST 数据从 Packet Capture 应用程序保护到 Web 服务器 API

php - 将 mysql select 查询与 php 变量连接起来?

encryption - ansible 是否安全地传输文件?