我在我的應用程序中使用了一個已經存在的數據庫(另請參閱1)。我用Java應用程序加密了數據庫。 在我的應用我嘗試閱讀下面的代碼encrypted_database,但我得到一個SQLiteException:文件加密或不是一個數據庫:SQLCipher已有數據庫的加密
SQLiteDatabase.loadLibs(mContext);
SQLiteDatabase dataBase = SQLiteDatabase.openDatabase(mPath, mPassword, null, SQLiteDatabase.OPEN_READONLY);
String query = "Select distinct _id from TABLE";
Cursor cursor = dataBase.rawQuery(query, null);
return cursor;
我已經加密我的數據庫SQLCipher,我也能閱讀數據,所以一切工作正常。
SQLCipher和現有數據庫的問題是我必須將完整的unencrypted_database複製到encrypted_database。在我的手機上這樣做需要很長時間。
我的想法是:在Java中編寫一個應用程序,用於加密數據庫並在您的應用程序中使用這個encrypted_database。這樣做的結果是我只需在我的應用程序中打開已經存在的encrypted_database,不需要進行復制。
現在,我寫了一個Java應用程序(基於,3),但仍有相關SQLCipher和一些問題的設計(4):
- 我怎麼可以把我的數據頁中的數據庫?在4中,數據庫頁面僅由其大小(1024字節)定義。但是我必須寫入我的encrypted_database文件來說「數據庫頁面啓動」或「數據庫頁面結束」
是salt和隨機初始化向量(iv)1024字節的一部分?
public static void main(String[] args) throws Exception{ outFile_enc = new FileOutputStream(mFileNameEncrypted); outFile_dec = new FileOutputStream(mFileNameDecrypted); int keyLength = 256; // salt salt = new byte[16]; Random rnd = new Random(); rnd.nextBytes(salt); int iterations = 4000; SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); KeySpec keySpec = new PBEKeySpec(mPassWord.toCharArray(), salt, iterations, keyLength); SecretKey passwordKey = keyFactory.generateSecret(keySpec); key = new SecretKeySpec(passwordKey.getEncoded(), "AES"); // creates a cipher and init it for encryption Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); AlgorithmParameters params = cipher.getParameters(); iv = params.getParameterSpec(IvParameterSpec.class).getIV(); encryptData(cipher); } public static void encryptData(Cipher cipher) throws Exception{ // File to encrypt inFile = new FileInputStream(mFileName); // unique random salt in the first 16 bytes of the file outFile_enc.write(salt); // Read file and encrypt its bytes byte[] input = new byte[64]; int bytesRead; while((bytesRead = inFile.read(input)) != -1){ byte[] output = cipher.update(input, 0, bytesRead); if(output != null) outFile_enc.write(output); } byte[] output = cipher.doFinal(); if(output != null) outFile_enc.write(output); // random initialization vector is stored at the end of a page outFile_enc.write(iv); inFile.close(); outFile_enc.flush(); outFile_enc.close(); }
我感謝每個幫助/想法/評論:)
謝謝你的回答。我看到了SQLCipher API,但我不明白如何解決我的問題。你的回答幫助我得到一個主意:)。我會在下次嘗試。 – owe