问题
I have decrypted a string and it works properly but when I am trying to encrypt the output string not getting the same result.
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, 0x65, 0x64, 0x65, 0x76
};
// KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), saltByte, iterCount, (keySize + (8 * ivLength))); // 32 + 16
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 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, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76
};
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), saltByte, iterCount, (keySize + (8 * ivLength))); // 32 + 16
// 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.ENCRYPT_MODE, key, 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;
}
current output
decrpted input : 9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
decrpted output: CUM006333
encrypted input : CUM006333
encrpted output: YVhOFyq9PAOkegIFDR/Ojw==
expected output
decrpted input : 9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
decrpted output: CUM006333
encrypted input : CUM006333
encrpted output: 9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
回答1:
This answer is nothing more than taking the comment from @Topaco into code, so all credits belong to him.
Kindly note my security warnings - increase the PBKDF2 iterations to a minimum of 10000 and do not use a static salt.
I changed some denotations so the variables have the data they are naming and the short routine is changed to a usual behavior (taking a plainText, encrypt it and then decrypt it).
The output is like expected:
plaintext input : CUM006333
encrypted output: 9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
decrypted input : 9AnBHCNAZkfJiY5DW+DwtHVGDmJtTwU4G3yg3JLeELc=
decrypted output: CUM006333
full code:
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, 0x65, 0x64, 0x65, 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, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76
};
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), saltByte, iterCount, (keySize + (8 * ivLength))); // 32 + 16
// 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.ENCRYPT_MODE, key, 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;
}
}
来源:https://stackoverflow.com/questions/64386104/aes-encryption-not-giving-expected-result