CryptoJS.<BlockCipher>.encrypt has two modes of encryption.
If you pass in a "key" that is a string, it will assume the "key" is a password. In order to derive a key from the password, it uses the OpenSSL-compatible derivation function
EVP_BytesToKey. This mode generates a new 8 byte random salt and uses it along with the password to generate a key and IV. Even if you explicitly pass in an IV, it won't be used.
results in a Base64-encoded ciphertext that contains the string "Salted__" at the beginning followed by the 8 byte salt and the actual ciphertext. You can explicitly split this before use with:
var ct = CryptoJS.AES.encrypt(msg, password); var saltHex = ct.salt.toString(); // random salt var ctHex = ct.ciphertext.toString(); // actual ciphertext var ivHex = ct.iv.toString(); // generated IV
Keys should have high entropy and be indistinguishable from random noise, which makes it hard for them to be brute-forced. The above mentioned
EVP_BytesToKey is not secure, because MD5 hashing is very fast, which enables an attacker to brute-force the password. You either need to use a really long password (20-30 characters) or use an appropriate key derivation function such as PBKDF2, which CryptoJS provides.