2016-05-08 14 views
4

Ich möchte ein einfaches Verschlüsselungs-/Entschlüsselungstool in Java implementieren. Deshalb fand ich ein kleines Tutorial auf: http://www.codejava.net/coding/file-encryption-and-decryption-simple-exampleAes Entschlüsselung in Java - Probleme mit der Auffüllung

ich einige Zeilen Code geändert, die Verschlüsselung von großen Dateien zu gewährleisten. Nun habe ich das Problem, dass die Entschlüsselung nicht funktioniert.

bekam ich die folgende Fehlermeldung/Ausnahme:

Error encrypting/decrypting file 
    at Algorithmus.Encryptor.doCrypto(Encryptor.java:71) 
    at Algorithmus.Encryptor.decrypt(Encryptor.java:39) 
    at GUI.MainWindow$encryptThread.run(MainWindow.java:838) 
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded 
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966) 
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824) 
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436) 
    at javax.crypto.Cipher.doFinal(Cipher.java:2165) 
    at Algorithmus.Encryptor.doCrypto(Encryptor.java:60) 
    ... 2 more 

Ich versuchte, den Transoformation Parameter AES/CBC/PKCS5Padding zu ändern, aber das hat keine Wirkung. Weiß jemand, wie man den gegebenen Code optimiert?

 private static final String ALGORITHM = "AES"; 

     private static final String TRANSFORMATION = "AES"; 

     public static void encrypt(String key, File inputFile, File outputFile) 
       throws ExtendedException { 
      doCrypto(Cipher.ENCRYPT_MODE, key, inputFile, outputFile); 
     } 

     public static void decrypt(String key, File inputFile, File outputFile) 
       throws ExtendedException { 
      doCrypto(Cipher.DECRYPT_MODE, key, inputFile, outputFile); 
     } 

     private static void doCrypto(int cipherMode, String key, File inputFile, 
       File outputFile) throws ExtendedException { 
      try { 
       Key secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM); 
       Cipher cipher = Cipher.getInstance(TRANSFORMATION); 
       cipher.init(cipherMode, secretKey); 

       FileInputStream inputStream = new FileInputStream(inputFile); 


       CipherOutputStream out = new CipherOutputStream(new FileOutputStream(outputFile), cipher); 
       byte[] buffer = new byte[8192]; 
       byte[] outputBytes = null; 
       FileOutputStream outputStream = new FileOutputStream(outputFile); 
       int count; 
       while ((count = inputStream.read(buffer)) > 0) 
       { 
        out.write(buffer, 0, count); 
        outputBytes = cipher.doFinal(buffer); 

       } 


       inputStream.close(); 
       outputStream.close(); 

      } catch (NoSuchPaddingException | NoSuchAlgorithmException 
        | InvalidKeyException | BadPaddingException 
        | IllegalBlockSizeException | IOException ex) { 
       throw new ExtendedException("Error encrypting/decrypting file", ex); 
      } 
     } 

Antwort

3

Verwenden Sie einfach die CipherOutputStream. Rufen Sie nicht cipher.doFinal(buffer) auf und vergessen Sie nicht, den Ausgabestrom zu schließen.

FileInputStream inputStream = new FileInputStream(inputFile); 
FileOutputStream fileout = new FileOutputStream(outputFile); 
CipherOutputStream out = new CipherOutputStream(fileout , cipher); 

try { 
    byte[] buffer = new byte[8192]; 
    int count; 

    while ((count = inputStream.read(buffer)) > 0) { 
     out.write(buffer, 0, count); 
    } 
} finally { 
    out.close(); 
    inputStream.close(); 
} 

Die CipherOutputStream verwaltet die Chiffre für Sie. Er ruft doFinal auf, wenn der Stream geschlossen wird, und löscht den internen Puffer.

+0

Vielen Dank. Es funktioniert perfekt! Aber wenn ich den falschen Passcode eingib, wird keine Ausnahme ausgelöst. Die entschlüsselte Datei wird erstellt, ist aber für Menschen nicht lesbar. – jollepe

+1

@jollepe Die AES/CBC-Verschlüsselung selbst bietet keine Authentifizierung des korrekten Passworts, wenn Sie eine MAC der verschlüsselten Daten hinzufügen und diese zur Verifizierung oder Verwendung von AES verwenden müssen/GCM. Das Zurückgeben eines Fehlers an den Benutzer für ungültiges Auffüllen muss vermieden werden oder ein Angreifer kann es in einem Auffüllen-oracle-Angriff ausnutzen. – zaph