2016-04-17 14 views
1

Ich benutze eine einfache CipherInput/OutputStream, um zu versuchen, Dateien in Android zu verschlüsseln/entschlüsseln.CipherOutputStream korrumpierenden Kopfzeilen in Android

Das Problem, das ich habe, ist, dass es scheint, die ersten paar Bytes der Datei zu korrumpieren, aber nicht den Rest. Hier ist ein Beispiel einer Ausgabe von einer einfachen Textdatei:

Originaltext:

"Test for Android cipher. The quick brown fox jumps over the lazy dog." 

Radelte durch Verschlüsselung und Entschlüsselung:

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

Hier ist mein Code:

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; 
} 

UPDATE:

wurde geraten, um explizit eine zufällige IV des Chiffre-Setup hinzufügen und hinzugefügt/geändert, um die folgenden Codezeilen um es zu erleichtern:

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)); 

mit dem gleichen Ergebnis endete. Die ersten paar Bytes der Textdatei waren noch immer beschädigt.

FINAL ANTWORT:

nicht sicher, was ich tat, aber je Vorschläge unten ich eine statische IV versucht hatte, und es war zeigte noch das gleiche Verhalten, aber ich zog die Erklärung und etwas passiert; hatte wahrscheinlich irgendwo einen Tippfehler. Das Problem wurde behoben, und hier ist der letzte Arbeitscode. Danke, alles was geholfen hat!

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; 
} 

Antwort

1

Legen Sie explizit eine zufällige IV und fügen Sie es mit Ihrem Chiffretext ein.

+0

Versucht, dass und leider nicht funktioniert: /. Gleiches Ergebnis. Die ersten paar Bytes der Datei sind beschädigt. Oben wurde ein Update hinzugefügt. – Nuvious

+0

Es ist ein Satz mit etwa 11 Wörtern, und Sie schaffen es immer noch, nur den ersten Teil davon zu lesen. Die IV muss während der Verschlüsselung und Entschlüsselung gleich sein. –

+0

Ich werde versuchen, ein Beispiel für den verschlüsselten Text zu erhalten, aber es verschlüsselt die gesamte Nachricht von vorne nach hinten; Was Sie sehen, ist die entschlüsselte Nachricht. Ich habe auch versucht, ein statisches 128-Bit-IV-Laster zu verwenden, das obige zufällige Setup und immer noch keine Freude. – Nuvious