2012-12-20 61 views
3

我在我的應用程序中使用了一個已經存在的數據庫(另請參閱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();  
    } 
    

我感謝每個幫助/想法/評論:)

回答

2

不建議試圖從頭創建一個SQLCipher文件的方法。格式比您所做的更復雜,並且它將重新生成有效的SQLCipher文件。相反,您應該只使用SQLCipher command line programencrypt your database進行分配。

+0

謝謝你的回答。我看到了SQLCipher API,但我不明白如何解決我的問題。你的回答幫助我得到一個主意:)。我會在下次嘗試。 – owe

相關問題