2016-09-14 114 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

相关问题