2016-04-17 14 views
1

私は単純なCipherInput/OutputStreamを使用して、アンドロイドのファイルを暗号化/復号化しようとしています。CipherOutputStreamがAndroidのヘッダを破損しています

私が抱えている問題は、ファイルの最初の数バイトが破損しているように見えることですが、残りの部分は破損していないようです。

オリジナルテキスト:

暗号化と復号を循環
"Test for Android cipher. The quick brown fox jumps over the lazy dog." 

:ここでは、単純なテキストファイルからの出力の例です

@ÍØJ­b¢çc°ÌHOšpher. The quick brown fox jumps over the the lazy dog. 

ここに私のコードは次のとおりです。

public static SecretKey generateKey(Context c, char[] passphraseOrPin) throws NoSuchAlgorithmException, InvalidKeySpecException { 
    // Number of PBKDF2 hardening rounds to use. Larger values increase 
    // computation time. You should select a value that causes computation 
    // to take >100ms. 
    byte[] salt = Settings.Secure.getString(c.getContentResolver(), 
      Settings.Secure.ANDROID_ID).getBytes(); 

    final int iterations = 1000; 

    final int outputKeyLength = 128; 

    SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
    KeySpec keySpec = new PBEKeySpec(passphraseOrPin, salt, iterations, outputKeyLength); 
    SecretKey secretKey = secretKeyFactory.generateSecret(keySpec); 
    Log.d("HIDEMYPICS","Secret Key: " + toHex(secretKey.getEncoded())); 
    return secretKey; 
} 

public static boolean decryptFileFromUri(Context context, Uri file, String keyphrase) { 
    try { 
     File f = new File(getRealPathFromURI(context, file)); 
     FileInputStream fis = new FileInputStream(f); 

     File ef = new File(f.toString().replace(".epf", "")); 
     FileOutputStream fos = new FileOutputStream(ef); 

     Log.d("HIDEMYPICS","Decrypting: " + f.toString()); 

     SecretKey key = generateKey(context, keyphrase.toCharArray()); 
     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.DECRYPT_MODE, key); 
     // Wrap the output stream 
     CipherOutputStream cos = new CipherOutputStream(fos, cipher); 
     // Write bytes 
     int b; 
     byte[] d = new byte[8]; 
     while ((b = fis.read(d)) != -1) { 
      cos.write(d, 0, b); 
     } 
     // Flush and close streams. 
     cos.flush(); 
     cos.close(); 
     fis.close(); 

     Log.d("HIDEMYPICS","Decrypted to: " + ef.toString()); 
     return true; 
    } catch (IOException e){ 
     e.printStackTrace(); 
    } catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeySpecException e) { 
     e.printStackTrace(); 
    } 
    return false; 
} 

public static boolean encryptFileFromUri(Context context, Uri file, String keyphrase) { 
    try { 
     File f = new File(getRealPathFromURI(context, file)); 
     FileInputStream fis = new FileInputStream(f); 

     File ef = new File(f.toString() + ".epf"); 
     FileOutputStream fos = new FileOutputStream(ef); 

     Log.d("HIDEMYPICS","Encrypting: " + f.toString()); 

     SecretKey key = generateKey(context, keyphrase.toCharArray()); 
     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE, key); 
     // Wrap the output stream 
     CipherOutputStream cos = new CipherOutputStream(fos, cipher); 
     // Write bytes 
     int b; 
     byte[] d = new byte[8]; 
     while ((b = fis.read(d)) != -1) { 
      cos.write(d, 0, b); 
     } 
     // Flush and close streams. 
     cos.flush(); 
     cos.close(); 
     fis.close(); 
     Log.d("HIDEMYPICS","Encrypted to: " + ef.toString()); 
     return true; 
    } catch (IOException e){ 
     e.printStackTrace(); 
    } catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeySpecException e) { 
     e.printStackTrace(); 
    } 
    return false; 
} 

更新:

は、明示的に暗号セットアップにランダムなIVを追加することをお勧めして、それを容易にするために、次のコード行を追加/変更された:

SecureRandom r = new SecureRandom(); 
     byte[] ivBytes = new byte[16]; 
     r.nextBytes(ivBytes); 

     SecretKey key = generateKey(context, keyphrase.toCharArray()); 
     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivBytes)); 

は同じ結果になってしまいました。テキストファイルの最初の数バイトはまだ破損していました。

FINAL ANSWER:しかし、提案あたり、私は静的IVを試していたし、それはまだ同じ挙動を示していたが、私は宣言を移動し、何かが起こったの下に、私が何をしたか

わかりません。おそらくどこかでタイプミスがありました。問題は解決されましたが、ここに最終的な作業コードがあります。助けてくれてありがとう!

private static final byte[] ivBytes = {109,15,57,79,75,112,50,91,18,18,107,127,65,68,12,69}; 

public static SecretKey generateKey(Context c, char[] passphraseOrPin) throws NoSuchAlgorithmException, InvalidKeySpecException { 
    // Number of PBKDF2 hardening rounds to use. Larger values increase 
    // computation time. You should select a value that causes computation 
    // to take >100ms. 
    byte[] salt = Settings.Secure.getString(c.getContentResolver(), 
      Settings.Secure.ANDROID_ID).getBytes(); 

    final int iterations = 1000; 

    final int outputKeyLength = 128; 

    SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
    KeySpec keySpec = new PBEKeySpec(passphraseOrPin, salt, iterations, outputKeyLength); 
    SecretKey secretKey = secretKeyFactory.generateSecret(keySpec); 
    return secretKey; 
} 

public static boolean decryptFileFromUri(Context context, Uri file, String keyphrase) { 
    try { 
     File f = new File(getRealPathFromURI(context, file)); 
     FileInputStream fis = new FileInputStream(f); 

     File ef = new File(f.toString().replace(".epf", "")); 
     FileOutputStream fos = new FileOutputStream(ef); 

     SecretKey key = generateKey(context, keyphrase.toCharArray()); 
     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

     cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivBytes)); 
     // Wrap the output stream 
     CipherInputStream cis = new CipherInputStream(fis, cipher); 
     // Write bytes 
     int b; 
     byte[] d = new byte[8]; 
     while ((b = cis.read(d)) != -1) { 
      fos.write(d, 0, b); 
      fos.flush(); 
     } 
     // Flush and close streams. 
     fos.close(); 
     cis.close(); 

     f.delete(); 
     return true; 
    } catch (IOException e){ 
     e.printStackTrace(); 
    } catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeySpecException e) { 
     e.printStackTrace(); 
    } catch (InvalidAlgorithmParameterException e) { 
     e.printStackTrace(); 
    } 
    return false; 
} 

public static boolean encryptFileFromUri(Context context, Uri file, String keyphrase) { 
    try { 
     File f = new File(getRealPathFromURI(context, file)); 
     FileInputStream fis = new FileInputStream(f); 

     File ef = new File(f.toString() + ".epf"); 
     FileOutputStream fos = new FileOutputStream(ef); 

     SecretKey key = generateKey(context, keyphrase.toCharArray()); 
     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivBytes)); 
     // Wrap the output stream 
     CipherOutputStream cos = new CipherOutputStream(fos, cipher); 
     // Write bytes 
     int b; 
     byte[] d = new byte[8]; 
     while ((b = fis.read(d)) != -1) { 
      cos.write(d, 0, b); 
      cos.flush(); 
     } 
     // Flush and close streams. 
     cos.close(); 
     fis.close(); 
     f.delete(); 
     return true; 
    } catch (IOException e){ 
     e.printStackTrace(); 
    } catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeySpecException e) { 
     e.printStackTrace(); 
    } catch (InvalidAlgorithmParameterException e) { 
     e.printStackTrace(); 
    } 
    return false; 
} 

答えて

1

乱数IVを明示的に設定して、暗号文に含めます。

+0

これを試してみましたが、残念ながらうまくいきませんでした。同じ結果。ファイルの最初の数バイトが壊れています。それに関する上記のアップデートを追加しました。 – Nuvious

+0

これは約11語の1つの文章ですが、それでもあなたはそれの最初の部分だけを読むことができます。 IVは、暗号化と解読の間に同じでなければなりません。 –

+0

私は暗号文の例を得ようとしますが、メッセージ全体を暗号化します。あなたが見ているのは解読されたメッセージです。私はまた、上記のランダムなセットアップとまだ喜びの静的な128ビットIVのバイスを使用してみました。 – Nuvious

関連する問題