I'm using javax.crypto.Cipher
to encrypt a file and then decrypt it but I'm still getting the BadPaddingException. The following class receives inputStream
from the input file and outputStream
for the output file.
Error
13:22:15,049 ERROR [STDERR] javax.crypto.BadPaddingException: Given final block not properly padded
13:22:15,081 ERROR [STDERR] at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
13:22:15,096 ERROR [STDERR] at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
13:22:15,128 ERROR [STDERR] at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
13:22:15,143 ERROR [STDERR] at javax.crypto.Cipher.doFinal(DashoA13*..)
Code
public class CipherAES implements Cipher {
private static final Logger logger = Logger.getLogger(CipherAES.class);
private Key key;
public CipherAES() {
this.key = generateKey();
}
private Key generateKey() {
try {
KeyGenerator generator;
generator = KeyGenerator.getInstance("AES");
generator.init(new SecureRandom());
return generator.generateKey();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
@Override
public void decrypt(InputStream inputStream, OutputStream outputStream) throws IOException {
try {
javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES");
cipher.init(javax.crypto.Cipher.DECRYPT_MODE, key);
byte[] raw = IOUtil.toByteArray(inputStream);
byte[] base64Decoded = Base64.decodeBase64(raw);
byte[] decryptedData = cipher.doFinal(base64Decoded);
outputStream.write(decryptedData);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} finally {
inputStream.close();
outputStream.close();
}
}
@Override
public void encrypt(InputStream inputStream, OutputStream outputStream) throws IOException {
try {
javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES");
cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key);
byte[] raw = IOUtil.toByteArray(inputStream);
byte[] encryptedData = cipher.doFinal(raw);
byte[] base64Encoded = Base64.encodeBase64(encryptedData);
outputStream.write(base64Encoded);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} finally {
inputStream.close();
outputStream.close();
}
}
}
LOG
# this is log from encryption
raw:
[97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122]
encrypted:
[92, -104, -48, -10, 95, -3, -21, 46, 27, -60, -115, 85, 114, -95, -126, 108, 88, -105, 94, -84, 86, 86, -75, -83, -73, 24, -109, 86, -34, 83, -35, 106]
base64Encoded:
[88, 74, 106, 81, 57, 108, 47, 57, 54, 121, 52, 98, 120, 73, 49, 86, 99, 113, 71, 67, 98, 70, 105, 88, 88, 113, 120, 87, 86, 114, 87, 116, 116, 120, 105, 84, 86, 116, 53, 84, 51, 87, 111, 61]
# this is from decryption
raw (this is the base64Encoded):
[88, 74,开发者_运维技巧 106, 81, 57, 108, 47, 57, 54, 121, 52, 98, 120, 73, 49, 86, 99, 113, 71, 67, 98, 70, 105, 88, 88, 113, 120, 87, 86, 114, 87, 116, 116, 120, 105, 84, 86, 116, 53, 84, 51, 87, 111, 61]
base64Decoded (this is the encrypted):
[92, -104, -48, -10, 95, -3, -21, 46, 27, -60, -115, 85, 114, -95, -126, 108, 88, -105, 94, -84, 86, 86, -75, -83, -73, 24, -109, 86, -34, 83, -35, 106]
decrypted (this should be the raw from the encryption):
I don't know - the exception is thrown
Well your encryption code seems somewhat flaky to start with:
byte[] raw = IOUtil.toByteArray(inputStream);
byte[] encryptedData = cipher.doFinal();
How about giving the cipher
the data it's meant to encrypt? I suspect you meant to pass in raw
to the doFinal
call.
I doubt that that's the complete problem, but it's at least a starting point.
EDIT for posterity: Judging by the comments, the problem was that different instances were being used for encryption and decryption, hence different keys.
BadPaddingException when decrypting encrypted stream is primarily due to saving encrypted data in wrong format
For details check out
http://themasterofmagik.wordpress.com/2014/03/19/simple-aes-encryption-and-decryption-in-java-part1/
It mentions which code was giving error and how it was resolved.
精彩评论