Hello I am using openssl to encrypt a string and JAVA code to decrypt it. My key is "SUDIPTA123". The command I am using to encrypt
encdata=$(echo -n "12345627678" | openssl enc -v -aes-256-cbc -base64 -nosalt -pass "pass:$key")
encdata contains /oUakLZnim7aPtpRySLRDw==.
Now I am using the follwoing JAVA code to decrypt encdata
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.KeySpec;
import java.util.Base64;
public class AESDecryptor {
public static void main(String[] args) {
String encryptedText = "/oUakLZnim7aPtpRySLRDw==";
String password = "SUDIPTA123";
try {
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
byte[] ivBytes = new byte[16];
System.arraycopy(encryptedBytes, 0, ivBytes, 0, 16);
byte[] encryptedData = new byte[encryptedBytes.length - 16];
System.arraycopy(encryptedBytes, 16, encryptedData, 0, encryptedData.length);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password.toCharArray(), ivBytes, 65536, 256);
SecretKeySpec secretKeySpec = new
SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(ivBytes));
byte[] decryptedData = cipher.doFinal(encryptedData);
String decryptedText = new String(decryptedData, "UTF-8");
System.out.println("Decrypted Text: " + decryptedText);
} catch (Exception e) {
e.printStackTrace();
}
}
}
After running the code decryptedText is empty string. I am not sure what I am doing wrong. Any help would be appreciated.
Decryption fails because OpenSSL statement and Java code apply different key derivation functions (KDFs): In the OpenSSL statement the default
EVP_BytesToKey()is used, in the Java code PBKDF2.In order for both codes to be compatible, the same KDF must be applied, i.e. if the OpenSSL statement is the reference,
EVP_BytesToKey()must be used in the Java code.There are various Java implementations on the web for
EVP_BytesToKey(), e.g. the one from BouncyCastle.Your decryption works if you replace the key and IV derivation part in your Java code, i.e. the complete first block inside the
try {}, with (using BouncyCastle):Security:
EVP_BytesToKey()is deprecated (since insecure) and should no longer be used. Reliable key derivation functions are Argon2 or at least PBKDF2. The latter is also supported by more modern OpenSSL versions (via the -pbkdf2 and -iter options).In the context of PBKDF2, use an iteration count that is as large as possible with acceptable performance (usually a few 100000).
Salted__, followed by an 8 bytes salt and the actual ciphertext.The salt and ciphertext must be separated during decryption. Afterwards, key and IV can be derived with passphrase and salt, and finally the actual ciphertext can be decrypted with the derived key and IV.