Java 使用 AES/ECB/NoPadding 加密/解密
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22034269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
encryption/decryption using AES/ECB/NoPadding
提问by S-T
Following are my encrypt/decrypt methods:
以下是我的加密/解密方法:
private String decrypt_data(String encData)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
String key = "bad8deadcafef00d";
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
System.out.println("Base64 decoded: "+Base64.decode(encData.getBytes()).length);
byte[] original = cipher.doFinal(Base64.decode(encData.getBytes()));
return new String(original).trim();
}
private String encrypt_data(String data)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
String key = "bad8deadcafef00d";
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
System.out.println("Base64 encoded: "+ Base64.encode(data.getBytes()).length);
byte[] original = cipher.doFinal(Base64.encode(data.getBytes()));
return new String(original);
}
So now when I am trying to encrypt, I am getting this exception:
所以现在当我尝试加密时,我收到了这个异常:
javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes
at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:854)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:828)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
I have tried with cipher instance AES/ECB/PKCS5Padding
in both encrypt and decrpt. It works only for encryption and not for decryption. I suppose padding is needed as data size is not multiple of 16bytes. 'data' byte length was printed as 152
so tried appending eight
\0
characters to data and then encrypt, it didn't work either.
我AES/ECB/PKCS5Padding
在 encrypt 和 decrpt 中都尝试过使用密码实例。它仅适用于加密,不适用于解密。我认为需要填充,因为数据大小不是 16 字节的倍数。'data' 字节长度被打印,152
因此尝试将eight
\0
字符附加到数据然后加密,它也不起作用。
回答by Ted Bigham
To address your specific problem, I thinkyou just need to add the 8 bytes padding like you tried, but use something that is valid in a java string (like spaces) instead.
为了解决您的具体问题,我认为您只需要像您尝试的那样添加 8 个字节的填充,而是使用在 java 字符串中有效的内容(如空格)。
回答by Ornicare
I saw another mistake in your code :
我在你的代码中看到了另一个错误:
Even if your encyption method get working, you're decryption method is not going to work. Indeed you are encrypting using Base64 followed bye AES. And you decrypt the whole thing using Base64 followed by AES.
即使您的加密方法有效,您的解密方法也不会起作用。实际上,您正在使用 Base64 加密,然后是 AES。然后您使用 Base64 和 AES 解密整个内容。
I am almost sure that this two type of encryption are not exchangeables. (you must decrypt AES then Base64).
我几乎可以肯定,这两种类型的加密是不可互换的。(您必须先解密 AES,然后再解密 Base64)。
Considering this answer : javax.crypto.IllegalBlockSizeException : Input length must be multiple of 16 when decrypting with padded cipher, without the use of padding (NoPadding arg), you have to use an input String with a length multiple of 16.
考虑到这个答案:javax.crypto.IllegalBlockSizeException :使用填充密码解密时,输入长度必须是 16 的倍数,而不使用填充(NoPadding arg),您必须使用长度倍数为 16 的输入字符串。
If we correct your code with my remark and if we let the cipher manage the padding, we get the following code, which works well :
如果我们用我的话更正你的代码,如果我们让密码管理填充,我们会得到以下代码,它运行良好:
private static String decrypt_data(String encData)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
String key = "bad8deadcafef00d";
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
System.out.println("Base64 decoded: "
+ Base64.decode(encData.getBytes()).length);
byte[] original = cipher
.doFinal(Base64.decode(encData.getBytes()));
return new String(original).trim();
}
private static String encrypt_data(String data)
throws Exception {
String key = "bad8deadcafef00d";
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
System.out.println("Base64 encoded: "
+ Base64.encode(data.getBytes()).length);
byte[] original = Base64.encode(cipher.doFinal(data.getBytes()));
return new String(original);
}