2016-06-02 10 views
0

Beim Verschlüsseln und Entschlüsseln einer Datei mit CipherInputStream und CipherOutputStream unterscheidet sich die entschlüsselte Datei vom Original. Während der Ausführung werden keine Fehler ausgegeben, aber das Original und das Ergebnis weisen unterschiedliche Hashwerte auf. Das Original und das Ergebnis sind ebenfalls exakt gleich groß. Es gibt keine Dateikollisionen/Überschreiben. Meine beste Vermutung ist bisher die Zeichencodierung.Die Java-Entschlüsselung bietet ein anderes Ergebnis als das Original

public void fileTest(File source, File output, String key) throws Exception { 
    Log.write("Starting file encryption/decryption test!"); 
    Util.charset = CharsetToolkit.guessEncoding(source, 4096, StandardCharsets.UTF_8); 
    Log.write("Using charset " + Util.charset.name()); 
    Log.write("Using key: " + key); 
    String oHash = Util.checksum(source); 
    Log.write("Original hash: " + oHash); 

    //Cipher setup 

    SecretKeySpec sks = Util.padKey(key); 
    Cipher eCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    Cipher dCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    eCipher.init(Cipher.ENCRYPT_MODE, sks, new IvParameterSpec(new byte[16])); 
    dCipher.init(Cipher.DECRYPT_MODE, sks, new IvParameterSpec(new byte[16])); 

    //IO setup 
    File tmpEncrypt = new File(source.getParent() + "/" + source.getName() + "-tmp"); 
    tmpEncrypt.createNewFile(); 
    output.createNewFile(); 
    Log.write("Encrypting to: " + tmpEncrypt.getAbsolutePath()); 
    InputStream fis = new FileInputStream(source); 
    InputStream enIn = new FileInputStream(tmpEncrypt); 
    OutputStream fos = new FileOutputStream(tmpEncrypt); 
    OutputStream clearOut = new FileOutputStream(output); 
    CipherInputStream cis = new CipherInputStream(enIn, dCipher); 
    CipherOutputStream cos = new CipherOutputStream(fos, eCipher); 

    //Encrypt 
    Log.write("Starting encryption process"); 
    int numRead = 0; 
    byte[] buffer = new byte[1024]; 
    while ((numRead = fis.read(buffer)) >= 0) { 
     cos.write(buffer, 0, numRead); 
    } 

    cos.close(); 
    fos.close(); 
    Log.write("Done!"); 

    Log.write("Encrypted hash: " + Util.checksum(output)); 

    //Decrypt 
    Log.write("Starting decryption process"); 
    int nr = 0; 
    byte[] b = new byte[1024]; 
    while ((nr = cis.read(b)) >= 0) { 
     clearOut.write(buffer, 0, nr); 
    } 
    clearOut.close(); 
    cis.close(); 
    fis.close(); 
    Log.write("Done!"); 

    String fHash = Util.checksum(output); 
    Log.write("Final hash: " + fHash); 

    if(fHash.equals(oHash)) { 
     Log.write("Success! The hashes are equal!"); 
    } else { 
     Log.write("Failure! Hashes are different!"); 
    } 
} 

EDIT: nahm ich Ihren Rat @zaph, und jetzt scheint es ein Problem mit dem Schreiben/Lesen Sie die Datei zu sein. Die Datei ist genau 40 Bytes lang. Hier ist die Hex-Dumps:

Key hex: 000074657374696e676b65797364617767313233 
IV hex: 0000000000000000000000000000000000000000 
Data IN: Lorem ipsum dolor sit amet orci aliquam. 
Data OUT: Lorem ipsum dolor sit amet orci Lorem ip. 

Odd, so scheint es, um die letzten 8 Bytes mit einer Wiederholung der ersten 8 Bytes überschrieben werden. Ich habe versucht, meine Puffergröße von 1024 Byte auf 8 Byte zu reduzieren, und es wurde noch seltsamer. Hex-Dump von 8 Byte-Test:

Key hex: 000074657374696e676b65797364617767313233 
IV hex: 0000000000000000000000000000000000000000 
Data IN: Lorem ipsum dolor sit amet orci aliquam. 
Data OUT: aliquam.aliquam.aliquam.aliquam.aliquam. 

etwas definitiv falsch mit der Art und Weise ist die erste Lese-/geschrieben wird, aber ich habe keine Ahnung, was los ist. Vielen Dank im Voraus!

+0

Haben Sie einen Unterschied zwischen der ursprünglichen und der entschlüsselten Datei gemacht? Bitte beachten Sie, dass der erste Hash nicht von der Originaldatei, sondern eine leere Zieldatei ist. –

+0

Erstellen Sie einen minimalen Testfall, eine kurze Datei, vielleicht 40 Byte lang. Hex dump den Schlüssel, iv und Daten für die Verschlüsselung und Entschlüsselung ein und aus. Vergleichen Sie für Diskrepanzen. Fügen Sie alles zur Frage hinzu, wenn Sie das Problem nicht finden können. – zaph

+0

Ich habe die Frage aktualisiert, danke für die Hilfe bisher. – user13356

Antwort

2

Gelöst es! Es gab ein Problem mit meinen while-Schleifen. Wie dieser:

Also ich ersetzte es stattdessen mit einer for-Schleife und alles funktioniert.

int segs = (int) (source.length()/4); 
for (int i = 0; i < segs; i++) { 
    fis.read(buffer); 
    cos.write(buffer, 0, buffer.length); 
} 
Verwandte Themen