3

アプリで既存のデータベースを使用しています ( 1も参照)。Java アプリケーションでデータベースを暗号化しました。私のアプリでは、次のコードで encrypted_database を読み込もうとしましたが、SQLiteException: file is encrypted or is not a database が発生します:

    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 アプリケーションを作成しました ( 23に基づく) が、SQLCipher とその設計に関連するいくつかの質問がまだあります ( 4 ):

  • データベースをデータベース ページに分割するにはどうすればよいですか? 4では、データベース ページはそのサイズ (1024 バイト) によって定義されます。しかし、「データベースページの開始」または「データベースページの終了」と言うために、encrypted_database ファイルに書き込まなければならないこと
  • ソルトとランダム初期化ベクトル (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();    
    }
    

すべてのヘルプ/アイデア/コメントに感謝します:)

4

1 に答える 1

2

SQLCipherファイルを最初から再作成しようとするアプローチはお勧めしません。フォーマットはあなたがしていることよりも複雑であり、それは有効なSQLCipherファイルを再現するのは簡単ではありません。代わりに、SQLCipherコマンドラインプログラムを使用して、配布用にデータベースを暗号化する必要があります。

于 2012-12-21T13:35:32.923 に答える