如何解决AES加密未提供预期结果
我已经解密了一个字符串,它可以正常工作,但是当我尝试加密输出字符串时,不会得到相同的结果。
public static void main(String[] args) {
// TODO Auto-generated method stub
String cipherstring = "9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=";
byte[] cipherByte = Base64.getDecoder().decode(cipherstring);
String cum006333 = decrypt(cipherstring,"KEY@CRISIL123");
System.out.println("decrpted output: " + cum006333);
String enc = encrypt(cum006333,"KEY@CRISIL123");
System.out.println("encrpted output: " + enc);
}
public static String decrypt(String cipherText,String passphrase) {
String s = null;
try {
System.out.println("decrpted input : " + cipherText);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] bytes = Base64.getDecoder().decode(cipherText);
int keySize = 256;
int iterCount = 1000;
int ivLength = 16;
byte[] saltByte = new byte[] {
0x49,0x76,0x61,0x6e,0x20,0x4d,0x65,0x64,0x76
};
// KeySpec spec = new PBEKeySpec(passphrase.toCharArray(),saltByte,iterCount,(keySize + (8 * ivLength))); // 32 + 16
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(),(keySize + 128)); // 32 + 16
byte[] rawKey = factory.generateSecret(spec).getEncoded(); // 48 bytes
byte[] keyDerived = Arrays.copyOf(rawKey,(keySize / 8)); // first 32 bytes
byte[] ivB = Arrays.copyOfRange(rawKey,(keySize / 8),rawKey.length); // last 16 bytes
SecretKey key = new SecretKeySpec(keyDerived,"AES");
IvParameterSpec iv = new IvParameterSpec(ivB);
cipher.init(Cipher.DECRYPT_MODE,key,iv);
//byte[] original = cipher.doFinal(data);
byte[] original = cipher.doFinal(bytes);
s = new String(original,StandardCharsets.UTF_16LE);
} catch (Exception ex) {
ex.printStackTrace();
}
return s;
}
public static String encrypt(String cipherText,String passphrase) {
String s = null;
try {
System.out.println("encrypted input : " + cipherText);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
// byte[] bytes = Base64.getDecoder().decode(cipherText);
cipherText = new String(cipherText.getBytes(),StandardCharsets.UTF_16LE);
int keySize = 256;
int iterCount = 1000;
int ivLength = 16;
byte[] saltByte = new byte[] {
0x49,0x76
};
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(),(keySize + (8 * ivLength))); // 32 + 16
// KeySpec spec = new PBEKeySpec(passphrase.toCharArray(),"AES");
IvParameterSpec iv = new IvParameterSpec(ivB);
cipher.init(Cipher.ENCRYPT_MODE,iv);
//byte[] original = cipher.doFinal(data);
byte[] original = cipher.doFinal(cipherText.getBytes());
s = Base64.getEncoder().encodeToString(original);
//s = new String(original,StandardCharsets.UTF_16LE);
} catch (Exception ex) {
ex.printStackTrace();
}
return s;
}
当前输出
decrpted input : 9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
decrpted output: CUM006333
encrypted input : CUM006333
encrpted output: YVhOFyq9PAOkegIFDR/Ojw==
预期产量
decrpted input : 9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
decrpted output: CUM006333
encrypted input : CUM006333
encrpted output: 9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
解决方法
这个答案无非就是将 @Topaco 中的评论纳入代码,因此所有荣誉归他所有。
请注意我的安全警告-将PBKDF2迭代次数增加到至少10000,并且不要使用静态盐。
我更改了一些表示法,以便变量获得它们正在命名的数据,并且将短例程更改为常规行为(采用plainText,对其进行加密,然后对其进行解密)。
输出与预期的一样:
plaintext input : CUM006333
encrypted output: 9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
decrypted input : 9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
decrypted output: CUM006333
完整代码:
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Base64;
public class MainSo {
public static void main(String[] args) {
// https://stackoverflow.com/questions/64386104/aes-encryption-not-giving-expected-result
String plainText = "CUM006333";
String passphrase = "KEY@CRISIL123";
String enc = encrypt(plainText,passphrase);
System.out.println("encrypted output: " + enc);
String dec = decrypt(enc,passphrase);
System.out.println("decrypted output: " + dec);
}
public static String decrypt(String cipherText,String passphrase) {
String s = null;
try {
System.out.println("decrypted input : " + cipherText);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] bytes = Base64.getDecoder().decode(cipherText);
int keySize = 256;
// ### SECURITY WARNING - use minimum 10000 iterations ###
int iterCount = 1000;
int ivLength = 16;
// ### SECURITY WARNING - don't use a static salt
byte[] saltByte = new byte[] {
0x49,0x76,0x61,0x6e,0x20,0x4d,0x65,0x64,0x76
};
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(),saltByte,iterCount,(keySize + 128)); // 32 + 16
byte[] rawKey = factory.generateSecret(spec).getEncoded(); // 48 bytes
byte[] keyDerived = Arrays.copyOf(rawKey,(keySize / 8)); // first 32 bytes
byte[] ivB = Arrays.copyOfRange(rawKey,(keySize / 8),rawKey.length); // last 16 bytes
SecretKey key = new SecretKeySpec(keyDerived,"AES");
IvParameterSpec iv = new IvParameterSpec(ivB);
cipher.init(Cipher.DECRYPT_MODE,key,iv);
//byte[] original = cipher.doFinal(data);
byte[] original = cipher.doFinal(bytes);
s = new String(original,StandardCharsets.UTF_16LE);
} catch (Exception ex) {
ex.printStackTrace();
}
return s;
}
public static String encrypt(String plainText,String passphrase) {
String s = null;
try {
System.out.println("plaintext input : " + plainText);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
// byte[] bytes = Base64.getDecoder().decode(cipherText);
//cipherText = new String(cipherText.getBytes(),StandardCharsets.UTF_16LE);
int keySize = 256;
// ### SECURITY WARNING - use minimum 10000 iterations ###
int iterCount = 1000;
int ivLength = 16;
// ### SECURITY WARNING - don't use a static salt
byte[] saltByte = new byte[] {
0x49,(keySize + (8 * ivLength))); // 32 + 16
// KeySpec spec = new PBEKeySpec(passphrase.toCharArray(),"AES");
IvParameterSpec iv = new IvParameterSpec(ivB);
cipher.init(Cipher.ENCRYPT_MODE,iv);
//byte[] original = cipher.doFinal(data);
byte[] cipherText = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_16LE));
//byte[] original = cipher.doFinal(cipherText.getBytes());
s = Base64.getEncoder().encodeToString(cipherText);
//s = new String(original,StandardCharsets.UTF_16LE);
} catch (Exception ex) {
ex.printStackTrace();
}
return s;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。