Chiffre doFinal pad block corrupted beim entschlüsseln der Datei mit AES
Erstelle ich ein Programm, das ermöglicht Benutzern das hochladen und herunterladen von verschlüsselten Dateien und entschlüsselt werden, wenn Sie die richtigen Berechtigungen haben, um so zu tun. Verschlüsseln und hochladen ist in Ordnung, und so ist der Download, aber wenn ich versuche zu entschlüsseln, bekomme ich den "pad block corrupted" - Fehler.
Was ich versuche zu tun ist, nehmen Sie die verschlüsselte Datei, und erstellen Sie dann eine Kopie, die Sie unverschlüsselt
Ich verkürzt, was ich konnte, also bitte nicht den Kommentar, dass es aussieht unvollständig.
KeyGen:
public static SecretKey genGroupSecretKey() {
try {
KeyGenerator keyGen = KeyGenerator.getInstance("AES", "BC");
keyGen.init(128);
return keyGen.generateKey();
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace(System.err);
}
return null;
}
Verschlüsseln:
try (FileInputStream fis = new FileInputStream(sourceFile)) {
response = Utils.decryptEnv((byte[]) tempResponse.getObjContents().get(0), fsSecretKey, ivSpec);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
do {
byte[] buf = new byte[4096];
int n = fis.read(buf); //can throw an IOException
else if (n < 0) {
System.out.println("Read error");
fis.close();
return false;
}
byte[] cipherBuf = cipher.doFinal(buf);
//send through socket blah blah blah
} while (fis.available() > 0);
Entschlüsseln:
...
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, secKey, ivSpec);
File file = new File("D_" + filename); //D_ for decrypted
FileOutputStream fos = null;
if (!file.exists()) {
file.createNewFile();
fos = new FileOutputStream(file);
}
try (FileInputStream fis = new FileInputStream(filename)) {
do {
byte[] buf = new byte[4096];
int n = fis.read(buf);
if (n < 0) {
System.out.println("Read error");
fis.close();
return false;
}
byte[] cipherBuf = cipher.doFinal(buf); //ERROR HERE
System.out.println("IS THIS WORKING WTF: " + new String(cipherBuf));
fos.write(cipherBuf, 0, n);
} while (fis.available() > 0);
fis.close();
fos.close();
return true;
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollten Sie Sie
Cipher.doFinal()
nur für den letzten block von Daten. Sie sollten beide ändern Ihre Verschlüsselungs-und Entschlüsselungs-code zu verwendenCipher.update()
für alle zwischen Daten und verwenden Sie einen einzigen AufrufCipher.doFinal()
am Ende. Es ist erlaubt, zu verwendenCipher.update()
für alle zwischen Daten-block und rufen Sie dieCipher.doFinal()
mit dem leeren array am Ende.Auch, Sie ignorieren einfach die return-Wert
fis.read(buf)
wenn Sie übergeben Sie die Daten aus dem stream gelesen, um die Chiffre.Zudem sind Sie mit
InputStream.available()
als Bedingung, um den Zyklus zu beenden. Auch wenn der code innerhalb des Zyklus wäre korrekt, erhalten Sie unvorhersehbare Ergebnisse durch falsche Auslösung des Zyklus Zustand.Verwenden Sie das folgende Muster für die Arbeit mit den Chiffren:
Überprüfen Sie die anderen Varianten der
Cipher.update()
- es ist möglich, zwei pre-reservierten Puffer zu minimieren und zusätzliche Zuweisungen.Prüfen Sie auch, ob Sie wiederverwenden können
javax.crypto.CipherInputStream
undjavax.crypto.CipherOutputStream
Klassen, so dass Sie nicht haben, um die Arbeit mit der Chiffre direkt.InputStream.read(byte[])
und Sie müssen es verwenden, wenn Sie übergeben die Daten an die nächste Klasse.Wenn das Ziel ist, nur um das verschlüsseln und entschlüsseln einer Datei das folgende Programm würde helfen.