处理解密方法时遇到问题。加密产生了正确的输出但是当我解密完全相同的加密字符串时(应该回到明文字符串中),它不起作用。
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字节的倍数)
答案 0 :(得分:3)
public String encryptString(String plaintext, String encryptionKey)
问题就在这里。 String不是二进制数据的容器。此方法应返回byte []。类似地,decrypt()方法应该使用byte []作为密文参数,而不是String。
答案 1 :(得分:1)
您应该使用在字符和字节之间进行1对1映射的编码,例如“ISO-8859-1”。所以将代码更改为
private static final String UNICODE_FORMAT = "ISO-8859-1";
解决了这个问题。
答案 2 :(得分:0)
这是我的代码
public static String encrypt(String data) throws Exception {
SecretKeySpec key = generateKey();
final Cipher c = Cipher.getInstance("AES/EAX/NoPadding", "BC");
c.init(Cipher.ENCRYPT_MODE, key, ivSpec);
byte[] encVal = c.doFinal(data.getBytes("UTF8"));
String encryptedValue = Hex.toHexString(encVal);
return encryptedValue;
}
public static String decrypt(String encryptedData) throws Exception {
Key key = generateKey();
final Cipher c = Cipher.getInstance("AES/EAX/NoPadding", "BC");
c.init(Cipher.DECRYPT_MODE, key, ivSpec);
byte[] ba = Hex.decode(encryptedData);
byte[] encVal = c.doFinal(ba);
return new String (encVal);
}