Java AES with CBC using passphrase

孤街醉人 提交于 2019-12-05 01:27:57

问题


I want to implement 256 key AES with CBC encryption with Java. Recipient sent me 256 bit passphrase as a String 'absnfjtyrufjdngjvhfgksdfrtifghkv' and it perfectly works using this openssl command:

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

The output in base64 format is : U2FsdGVkX1/yA4J8T+i1M3IZS+TO/V29rBJNl2P88oI=

When i decript it, it returns original input string :

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

My problem is that i cannot make make my encryption work in java and decrypt it with above command. I know that my key should be generated using my passphrase. Below is example of my code where IV is generated randomly and key is generating using passphrase and 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 do run this:

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

I get 'bad magic number' error. What step of java encryption I'm doing wrong?


回答1:


According to this answer, OpenSSL uses a different key derivation algorithm than what you are using in your Java code. Therefore, the key used to encrypt will be different in your OpenSSL command and in your Java program, so the output will be different and incompatible.

You should also check the documentation of the key derivation function in OpenSSL. Apparently it uses MD5 in the algorithm, while your Java code is using SHA1. They won't output the same key.

You have to specify exactly the same key derivation function, or specify the key directly, instead of deriving it from a passphrase.

Finally, avoid creating yourself a key derivation function (that you could easily implement using bash and using Java) and stick to standards, if security is a concern (if it is not, why bother using crypto?); it is most probable that the algorithm will be broken.



来源:https://stackoverflow.com/questions/14695766/java-aes-with-cbc-using-passphrase

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!