How to decrypt a cryptojs AES encrypted message at the java server side?
aes, cryptojs, encryption, java
Solution
This part of your code is wrong:
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, 100, 128/32);
//->---------------------------------------------------------------------^^^^^^^
The `128/32` value is erroneous. You need either `128`, `192` or `256`. Currently you have the equivalent of `4`, which seems to result in no output at all from the PBKDF2 function.
Also, in Java you should use `DatatypeConverter.parseHexBinary()`, or similar, to convert hex into bytes. Currently you are just calling `getBytes()` which isn't right.
Finally, you need to specify CBC mode and PKCS#5 padding in order to match your Javascript code. So change the line to:
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
Problem
I have the following cryptojs based javascript encryption/decryption functions which works perfectly fine. I use a random salt, random iv value and a specific password while encrypting the message using cryptpjs. I reuse the same salt, iv and the password to generate the key while decrypting the encrypted message. This part works well.. ``` function encrypt(){ var salt = CryptoJS.lib.WordArray.random(128/8); var iv = CryptoJS.lib.WordArray.random(128/8); console.log('salt '+ salt ); console.log('iv '+ iv ); var key128Bits = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 128/32 }); console.log( 'key128Bits '+ key128Bits); var key128Bits100Iterations = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 128/32, iterations: 100 }); console.log( 'key128Bits100Iterations '+ key128Bits100Iterations); var encrypted = CryptoJS.AES.encrypt("Message", key128Bits100Iterations, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); console.log('encrypted '+ encrypted ); } function decrypt(){ var salt = CryptoJS.enc.Hex.parse("4acfedc7dc72a9003a0dd721d7642bde"); var iv = CryptoJS.enc.Hex.parse("69135769514102d0eded589ff874cacd"); var encrypted = "PU7jfTmkyvD71ZtISKFcUQ=="; console.log('salt '+ salt ); console.log('iv '+ iv ); var key = CryptoJS.PBKDF2("Secret Passphrase", salt, { keySize: 128/32, iterations: 100 }); console.log( 'key '+ key); var decrypt = CryptoJS.AES.decrypt(encrypted, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); var ddd = decrypt.toString(CryptoJS.enc.Utf8); console.log('ddd '+ddd); } ``` But the issue starts when I try to decrypt the same encrypted text at the java server side. I want the encrypted message to be decrypted by my java server code. Here is the Java code that I wrote: ``` public static void main(String args[]) throws Exception{ String password = "Secret Passphrase"; String salt = "4acfedc7dc72a9003a0dd721d7642bde"; String iv = "69135769514102d0eded589ff874cacd"; String encrypted = "PU7jfTmkyvD71ZtISKFcUQ=="; byte[] saltBytes = salt.getBytes(); //hexStringToByteArray(salt); byte[] ivBytes = iv.getBytes();//hexStringToByteArray(iv); IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes); SecretKeySpec sKey = (SecretKeySpec) generateKeyFromPassword(password, saltBytes); System.out.println( decrypt( encrypted , sKey ,ivParameterSpec)); } public static SecretKey generateKeyFromPassword(String password, byte[] saltBytes) throws GeneralSecurityException { KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, 100, 128/32); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); SecretKey secretKey = keyFactory.generateSecret(keySpec); return new SecretKeySpec(secretKey.getEncoded(), "AES"); } public static String decrypt(String encryptedData, SecretKeySpec sKey, IvParameterSpec ivParameterSpec) throws Exception { Cipher c = Cipher.getInstance("AES"); c.init(Cipher.DECRYPT_MODE, sKey, ivParameterSpec); byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData); byte[] decValue = c.doFinal(decordedValue); String decryptedValue = new String(decValue); return decryptedValue; } ``` But I get the following exception: ``` Exception breakpoint: SecretKeySpec.java:96, java.lang.IllegalArgumentException, Empty key Exception in thread "main" java.lang.IllegalArgumentException: Empty key at javax.crypto.spec.SecretKeySpec.<init>(SecretKeySpec.java:96) ``` I have no idea what I should do