Background: The application that I am working on is supposed to work offline. I should encrypt some text data using a password as a key at the java server side. The encrypted data is passed to the HTML5 page and at the client side using crypto-js library the server encrypted data should be decrypted.
My issue: In order to encrypt my message in such a way that the client can decrypt it with crypt-js (using a user entered password), I need to know the exact steps that crypto-js expects while encrypting a message.
What I need to know: I have the following encryption code which does the encryption of a message at the client side using crypto-js.
var message = "my message text";
var password = "user password";
var encrypted = CryptoJS.AES.encrypt( message ,password );
console.log(encrypted.toString());
I need to know the AES parameters used by CryptoJS while encrypting a message(Not sure what they are, but it sounds like: key size (256), padding (pkcs5), mode (CBC), PBE algorithm (PBKDF2), salt (random), iteration count (100)) . It would be a great help if some one could confirm it...I been trying to solve this mystery for the last few days?.
I need to know the different steps performed by CryptoJS while AES encrypting a message
I'm looking at the documentation here:
Stuff for generating the key:
You can set the parameters by hand, which is maybe safer than relying on the defaults, e.g. some pseudo-code based on the examples in the documentation:
You will probably have to experiment. I'd take it one step at a time. Get the password-based keys to match by fiddling those parameters, then get the ciphertext to match, then figure out decryption. Avoid the urge to simplify things like skipping the IV or using ECB.
CryptoJS uses the non-standardized OpenSSL KDF for key derivation (EvpKDF) with MD5 as the hashing algorithm and 1 iteration. The IV is also derived from the password which means that only the actual ciphertext, the password and the salt are needed to decrypt this on Java side.
In other words, PBKDF2 is not used for key derivation in password mode of CryptoJS. By default AES-256 is used in CBC mode with PKCS5 padding (which is the same as PKCS7 padding). Keep in mind that you might need the JCE Unlimited Strength Jurisdiction Policy Files. See also Why there are limitations on using encryption with keys beyond certain length?
The following code recreates the KDF in Java (
keySize
andivSize
are 8 respectively 4 for AES-256 and come from ).Here is the complete class for reference:
and the JavaScript code which was used for the generation of the values in the Java code:
Following @Artjom B's great answer both on this question and here for python users, I am joining the full java code that helped me decrypt a string that was encrypted this way
This piece of Java code is useful when you only know the password (i.e. salt was not sent with the encrypted string):