【发布时间】:2018-09-07 18:10:16
【问题描述】:
我正在尝试使用 AES 加密/解密 python 和 java 中的字符串,两者的加密结果相同。加密工作正常,但是当我尝试在 java 中解密字符串时,它向我显示了这个错误( javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher )。在python中它工作正常。 java解密有什么问题?
private static String toHexString(byte[] data) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; ++i) {
String s = Integer.toHexString(data[i] & 0XFF);
buf.append((s.length() == 1) ? ("0" + s) : s);
}
return buf.toString();
}
public static String encrypt(String input, String key) {
byte[] crypted = null;
try {
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skey);
crypted = cipher.doFinal(input.getBytes());
final String encryptedString = toHexString(Base64.encodeBase64(crypted));
return encryptedString;
} catch (Exception e) {
System.out.println(e.toString());
}
return "";
}
public static String decrypt(String encrypted, String key) {
char[] ch= encrypted.toCharArray();
try {
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher2 = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher2.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] h =Hex.decodeHex(ch);
String de = new String(Base64.decodeBase64(cipher2.doFinal(Hex.decodeHex(ch))),"UTF-8");
return de;
} catch (Exception e) {
System.out.println(e.toString());
}
return null;
}
【问题讨论】:
-
您需要检查加密后和解密前加密字节的字节长度是否相同。该错误告诉您您正在尝试解密长度不是 16 倍数的字节数组。某处的东西要么丢失字节,要么添加字节。有时字符串处理会添加不需要的换行符等。最好逐字节检查这两个字节数组,看看差异在哪里。
-
你为什么同时使用base64和十六进制编码?我认为一个就足够了
-
1.如果您无法解密,您怎么知道“加密工作正常”?仅仅因为没有错误指示并不意味着它按预期正常工作。 2.
javax.crypto.IllegalBlockSizeException表示要解密的数据大小不正确,必须是16字节的倍数。 3.提供测试密钥、数据和加密数据。 3. 最好的猜测是编码不匹配,参见上面的第 3 点。 -
不要在新作品中使用 ECB 模式并尽快更新旧作品,它不安全,请参阅ECB mode,向下滚动到企鹅。而是使用带有随机IV的CBC模式,只需在加密数据前加上IV用于解密即可,它不需要保密。
标签: java encryption aes