2016-09-14 111 views
2

我的資產中有一個數據庫文件,我將其複製到應用程序數據庫文件夾中。複製後(它工作),我想用SQLCipher加密複製的數據庫。在Android中使用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()); 
     } 
    } 
} 

}

回答

1

我解決了,我寫我的解決方案作爲未來的參考。我只是得到錯誤的路徑

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

} 
0

我們對SQLCipher內加密明文SQLite數據庫的例子Android test suitehere。此外,您可以嘗試調用靜態SQLiteDatabase.loadLibs(context);,而不是嘗試在實例字段上調用它。

+0

這是路徑的錯誤,SQLCipher是這樣做的權利;)現在,我發展我的DatabaseHelper類,以管理未加密的數據庫(「」通)和加密的一個太 – riccardo91

相關問題