javax.crypto.BadPaddingException AES 256 CBC 加密
我正在尝试使用 java 中的 PKCS5Padding 编写 AES 256 CBC 加密的加密/解密方法。我目前正在尝试从另一个来源解密一些 Base64 编码的加密文本。
代码如下: (这只是测试数据,所以不敏感)
// JUnit Test
@Test
public void testDecrypt() {
String cipherText = "rrAwZQCAIj19XauZE6tQEg/HQuWB7gw+1uVO0hylyWyCSJo/y7uB6Xj4BRVi+a3qY9GQ/ahjPdUF/kSHptt6QttkvQf89JS13Mo3mRAnaDK/8uoRur8TDuKzLtCSjaMAg72LqObx04+yLd9hI2krtCaWd2saCLP/cWvTQ9oc1xQ=";
String iv = "o1clHzdEkUV4sFj72VwDFQ==";
String syncKey = "gbh7teqqcgyzd65svjgibd7tqy";
SecretKeySpec key = new SecretKeySpec(convertFromBase32(syncKey), "AES");
byte[] cipherBytes = convertFromBase64(cipherText);
System.out.println(cipherBytes.length);
Encrypted d = Crypto.decrypt(new Encrypted(cipherBytes, key,
convertFromBase64(iv)));
String decryptedText = new String(d.getCipherText());
}
// Actual Code
public static Encrypted decrypt(Encrypted encrypted) {
// Initialize the Cipher
Cipher cipher = null;
IvParameterSpec ivParam = new IvParameterSpec(
encrypted.getInitializationVector());
try {
cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, encrypted.getSymmetricKey(),
ivParam);
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (NoSuchPaddingException e1) {
e1.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
byte[] outputBytes = cryptCommon(cipher, encrypted.getCipherText());
Encrypted decrypted = new Encrypted(outputBytes,
encrypted.getSymmetricKey(), cipher.getIV());
return decrypted;
}
private static byte[] cryptCommon(Cipher cipher, byte[] inputBytes) {
byte[] outputBytes = null;
try {
outputBytes = cipher.doFinal(inputBytes);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return outputBytes;
}
我已经检查了从 Base64 解码后的 byte[] 的长度,它们的长度可被块大小整除(16 字节块大小为 128 字节)。
这是我得到的堆栈跟踪:
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at com.mozilla.android.sync.Crypto.cryptCommon(Crypto.java:77)
at com.mozilla.android.sync.Crypto.decrypt(Crypto.java:69)
at com.mozilla.android.sync.test.CryptoTests.testDecrypt(CryptoTests.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
非常感谢任何帮助。谢谢!
I am trying to write encrypt/decrypt methods for AES 256 CBC encryption using PKCS5Padding in java. I am currently trying to decrypt some encrypted text from another source which is Base64 encoded.
Code below:
(This is just test data so it isn't sensitive)
// JUnit Test
@Test
public void testDecrypt() {
String cipherText = "rrAwZQCAIj19XauZE6tQEg/HQuWB7gw+1uVO0hylyWyCSJo/y7uB6Xj4BRVi+a3qY9GQ/ahjPdUF/kSHptt6QttkvQf89JS13Mo3mRAnaDK/8uoRur8TDuKzLtCSjaMAg72LqObx04+yLd9hI2krtCaWd2saCLP/cWvTQ9oc1xQ=";
String iv = "o1clHzdEkUV4sFj72VwDFQ==";
String syncKey = "gbh7teqqcgyzd65svjgibd7tqy";
SecretKeySpec key = new SecretKeySpec(convertFromBase32(syncKey), "AES");
byte[] cipherBytes = convertFromBase64(cipherText);
System.out.println(cipherBytes.length);
Encrypted d = Crypto.decrypt(new Encrypted(cipherBytes, key,
convertFromBase64(iv)));
String decryptedText = new String(d.getCipherText());
}
// Actual Code
public static Encrypted decrypt(Encrypted encrypted) {
// Initialize the Cipher
Cipher cipher = null;
IvParameterSpec ivParam = new IvParameterSpec(
encrypted.getInitializationVector());
try {
cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, encrypted.getSymmetricKey(),
ivParam);
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (NoSuchPaddingException e1) {
e1.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
byte[] outputBytes = cryptCommon(cipher, encrypted.getCipherText());
Encrypted decrypted = new Encrypted(outputBytes,
encrypted.getSymmetricKey(), cipher.getIV());
return decrypted;
}
private static byte[] cryptCommon(Cipher cipher, byte[] inputBytes) {
byte[] outputBytes = null;
try {
outputBytes = cipher.doFinal(inputBytes);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return outputBytes;
}
The I've check the lengths of the byte[] after decoding from Base64 and they are of length divisible by block size (128 bytes for a 16 byte block size).
Here is the stack trace I'm getting:
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at com.mozilla.android.sync.Crypto.cryptCommon(Crypto.java:77)
at com.mozilla.android.sync.Crypto.decrypt(Crypto.java:69)
at com.mozilla.android.sync.test.CryptoTests.testDecrypt(CryptoTests.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Any help is much appreciated. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在密码学中,一切都必须精确。您是否将加密和解密方法都设置为 PKCS5 填充?您是否检查过加密方法生成的字节是否与解密函数消耗的字节完全匹配?
您是否检查过两个密钥逐字节完全匹配?您曾经使用过 Base32,这有点不寻常。
我建议将您的测试分解为更小的部分,以便您可以显式检查加密和解密的每个参数的匹配情况。确保将每个参数检查为字节数组,即不涉及 Base64 或其他类型的转换。
In cryptography everything has to be exact. Have you set both encrypt and decrypt methods to PKCS5 padding? Have you checked that the bytes produced by the encryption method exactly match the bytes consumed by the decryption function?
Have you checked that the two keys exactly match, byte for byte? You are using Base32 at one point, and that is a bit unusual.
I would suggest breaking down your test into much smaller pieces, so you can explicitly check the match for every parameter for both encryption and decryption. Make sure that you check each parameter as a byte array, i.e. not involving conversion to or from Base64 or whatever.