【发布时间】:2014-07-15 11:35:55
【问题描述】:
我在处理解密方法时遇到问题。加密产生了正确的输出,但是当我解密完全相同的加密字符串(应该回到明文字符串)时,它不起作用。
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class Samp {
private static String IV = "aaaaaaaaaaaaaaaa";
private static final String UNICODE_FORMAT = "UTF8";
private String padd(String plaintext) {
while (plaintext.length() % 16 != 0) {
plaintext += "\0";
}
return plaintext;
}
public String encryptString(String plaintext, String encryptionKey) {
try {
byte[] cipher = encrypt(padd(plaintext), encryptionKey);
return new String(cipher, UNICODE_FORMAT);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public String decryptString(String encString, String encryptionKey) {
try {
System.out.println("**** decryptString ****");
System.out.println("enc = " + encString);
System.out.println("key = " + encryptionKey);
String decrypted = decrypt(encString.getBytes(UNICODE_FORMAT), encryptionKey);
return decrypted;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
private static byte[] encrypt(String plainText, String encryptionKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes(UNICODE_FORMAT), "AES");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IV.getBytes(UNICODE_FORMAT)));
return cipher.doFinal(plainText.getBytes(UNICODE_FORMAT));
}
private static String decrypt(byte[] cipherText, String encryptionKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes(UNICODE_FORMAT), "AES");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(IV.getBytes(UNICODE_FORMAT)));
return new String(cipher.doFinal(cipherText), UNICODE_FORMAT);
}
// implement methods here
// using AES simple encryption
public static void main(String[] args){
String plaintext = "Hello World!";
String key = "asdfqaqwsaerdqsw";
Samp s = new Samp();
String enc = s.encryptString(plaintext, key);
System.out.println("encrypted string = " + enc);
String dec = s.decryptString(enc, key);
System.out.println("decrypted string = " + dec);
}
}
我已经看到了这个post,它和我的问题一样。我遵循了建议(更改 getBytes() -> getBytes(UNICODE_FORMAT)),但它仍然是一样的。我仍然得到一个异常(javax.crypto.IllegalBlockSizeException:输入长度不是 16 字节的倍数)
【问题讨论】:
-
如果您使用
NoPadding算法,为什么要在padd中填充16 个字节 -
不填充就不行了,所以我决定填充明文就可以了
-
请注意,用零字符填充是不明确的:在解密时无法判断尾随零是原始字符串的一部分还是填充的一部分。
-
是的,我也注意到了。你有什么建议@JeffreyHantin
-
PKCS#7 padding 是明确的:填充由 n 个尾随字节组成,所有值 n。
标签: java encryption cryptography