Java AES with CBC using passphrase

I want to implement 256 CBC encrypted AES keys from Java. The receiver sent me a 256 bit passphrase as the string "absnfjtyrufjdngjvhfgksdfrtifghkv" and it works fine with this openssl command:

 echo test | openssl enc  -aes-256-cbc -a -k 'absnfjtyrufjdngjvhfgksdfrtifghkv'

      

Output signal in base64 format: U2FsdGVkX1 / yA4J8T + i1M3IZS + TO / V29rBJNl2P88oI =

When I decript it, it returns the original input string:

 echo U2FsdGVkX1/yA4J8T+i1M3IZS+TO/V29rBJNl2P88oI= | openssl enc -d -aes-256-cbc -a -k 'absnfjtyrufjdngjvhfgksdfrtifghkv'     

      

My problem is that I cannot get my encryption work to work in java and decrypt it with the above command. I know my key should be generated using my passphrase. Below is an example of my code where the IV is randomly generated and the key is generated using a passphrase and a random salt.

byte[] input = "test".getBytes();
String passphrase = "absnfjtyrufjdngjvhfgksdfrtifghkv";
int saltLength = 8; 

SecureRandom random = new SecureRandom();

//randomly generate salt
byte[] salt = new byte[saltLength];
random.nextBytes(salt);

// generating key from passphrase and salt
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), salt, 1024, 256);
SecretKey key = factory.generateSecret(spec);
SecretKey kspec = new SecretKeySpec(key.getEncoded(), "AES");

// randomly generate IV
byte iv[] = new byte[16];
random.nextBytes(iv);
IvParameterSpec ips = new IvParameterSpec(iv);

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, kspec, ips);
byte[] encryptedData = c.doFinal(input);
System.out.println(new String(Base64.encodeBase64(encryptedData)));

      

My java base64 output is XimWIM + 8UewzobFOMfevaw == and when I try this:

echo XimWIM+8UewzobFOMfevaw= | openssl enc -d -aes-256-cbc -a -k   'absnfjtyrufjdngjvhfgksdfrtifghkv'

      

I am getting a "bad magic number" error. What java encryption step am I doing wrong?

+3


source to share


1 answer


As per this answer, OpenSSL uses a different key derivation algorithm than the one you are using in your Java code. Therefore, the key used for encryption will be different in your OpenSSL command and your Java program, so the output will be different and incompatible.

You should also check the documentation for the Key Derivation Function in OpenSSL. Apparently it is using MD5 in the algorithm while your Java code is using SHA1. They will not give out the same key.



You must specify the exact same key derivation function, or you must specify the key directly, rather than inferring it from the passphrase.

Finally, don't make yourself a key derivation function (which you can easily implement with bash and using Java) and stick to standards if security is an issue (if it isn't, why use crypto?); the algorithm is most likely to be broken.

+4


source







All Articles