BadPaddingException: pad block corrupted
Ich versuche eine Datei entschlüsseln, die in Java, die verschlüsselt wurde in C# mit dem Rijndael-CBC/PKCS7. Ich bekomme immer folgende exception:
javax.crypto.BadPaddingException: pad block corrupted
bei org.bouncycastle.jce.Anbieter.JCEBlockCipher.engineDoFinal(Unknown Source)
bei javax.crypto.- Chiffre.doFinal(DashoA13*..)
bei AESFileDecrypter.entschlüsseln(AESFileDecrypter.java:57)
wenn die doFinal(inpbytes)
Methode wird aufgerufen, durch den web-server das erste byte[]. Ich vermute, dass dies ist ein problem mit dem Schlüssel oder IV. Ich habe die verschlüsselten Dateien auf meinem Dateisystem für die Prüfung. Gibt es etwas, dass jeder sehen kann, grell falsch mit meinem code unten?
***keyStr base64-codiert
public AESFileDecrypter(String keyStr){
try {
Security.addProvider(new BouncyCastleProvider());
convertIvParameter();
key = new sun.misc.BASE64Decoder().decodeBuffer(keyStr);
//use the passed in Base64 decoded key to create a key object
decryptKey = new SecretKeySpec(key, "AES");
//specify the encryption algorithm
decryptCipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
//make a parameter object for the initialization vector(IV)
IvParameterSpec ivs = new IvParameterSpec(_defaultIv);
//initialize the decrypter to the correct mode, key used and IV
decryptCipher.init(Cipher.DECRYPT_MODE, decryptKey, ivs);
}
catch (Exception e) {
e.printStackTrace();
}
}
public void convertIvParameter() {
int[] iv = new int[] {11, 190, 165, 33, 68, 88, 11, 200, 245, 35, 68, 23, 60, 24, 223, 67};
_defaultIv = new byte[16];
for(int x = 0; x < _defaultIv.length; x++) {
_defaultIv[x] = (byte)iv[x];
}
}
public void decryptUpdate(byte[] inpBytes) throws Exception {
//decrypt the byte passed in from the web server
decryptCipher.update(inpBytes);
}
public byte[] decryptFinal() throws Exception {
//decrypt the byte passed in from the web server
return decryptCipher.doFinal();
}
//sends bytes to the client for diaply
private void sendBytes(FileInputStream fis, OutputStream os)throws Exception {
//set the buffer size to send 4k segments of data
aesFileDecrypter = new AESFileDecrypter(<Insert Key string here>);
byte[] buffer = new byte[4096];
int bytes = 0, totalBytes = fis.available();
//while there is still data to be sent keep looping and write the data
//to the output stream as the buffer is filled
try {
while ((bytes = fis.read(buffer)) != -1) {
aesFileDecrypter.decryptUpdate(buffer);
//os.write(buffer, 0, bytes);
}
os.write(aesFileDecrypter.decryptFinal(), 0, totalBytes);
}
catch(Exception e) {
e.printStackTrace();
}
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Erstens, nur klar zu sein, aus den Kommentaren unten, sollten Sie nicht rufen Sie doFinal() auf jedem block, weil doFinal() erwartet keine Polsterung am Ende, die obviouslly wird nicht da sein, in der mittleren Blöcke. Entweder (a) Aufruf der update() an intermediate data, dann doFinal() am Ende, oder (b) vereinbaren Sie einfach alle Ihre Daten in einem Puffer-oder byte-array und call doFinal() einmal auf der ganzen Menge Arbeit.
Es ist nicht klar aus dem code, den Sie gepostet, dass das ist eigentlich das, was du tust, aber es sollte erwähnt werden, nur für den Fall.
Gelingt das nicht, dann als ersten Schritt zu Debuggen, ich würde vorschlagen, je nachdem, welcher dieser zwei ist einfacher für Sie:
Soweit ich mich erinnere, hat C# eine vorzeichenlose bytes (wohingegen Java signed) also es gibt ein paar Orte, wo es Raum für Dinge, die subtil schief geht, werden mit byte-Fehler.
Dem ich begegnet diesem problem vor.
Als ich schrieb einige code zu tun, Verschlüsselung und Entschlüsselung, wie diese:
Vergaß ich die ersten
IvParameterSpec(new byte[cipher.getBlockSize()])
beim verschlüsseln von Daten, dann bekam ich eine Ausnahme "pad block corrupted", so sollten Sie vielleicht überprüfen Sie die encryption-code.Soweit ich weiß AES basiert auf dem Rijndael, aber die Angabe ist nicht genau das gleiche. Ich würde vorschlagen, um zu überprüfen, die Schlüssel und block-Größe, die Sie verwenden, um Chiffre in C# und die Größen bei Java. (.Die Netto-Unterschiede zwischen Rijndael und AES).
Die doFinal() wurde der Untergang der code oben, und ich landete genau mit cipher-streams statt der update/doFinal Ansatz. Auf diese Weise könnte ich mit dem FileInputStream und meine Chiffre als Parameter für den CipherInputStream und übergeben die Ausgabe an den web-browser durch einen Ausgabestrom. Brechen Sie das update und doFinal in Ihre eigene Methode fordert, die Aufgabe viel schwieriger, und beide Methoden gelöscht wurden, aus dem decrypter-Klasse (verlassen einer while-Schleife, die Lesen in Blöcken von Daten und der Ausgabe an den browser). Der Hüpfburg-Anbieter war auch in diesem Fall nicht benötigt und PKCS5Padding war genug, das war gegeben durch das SunJCE.