'CryptoJS AES decrypt Hex String?
This is sort of a part two to the question Trying to print hex string with CryptoJS
Basically, I have a function that uses CryptoJS to encrypt a message and spit out the cypher text as a hex string.
function EncryptAES(text, key) {
var encrypted = CryptoJS.AES.encrypt(text, key);
return encrypted.ciphertext.toString()
}
I want to write a function DecryptAES that takes the hex string, key, and salt (which I apparently need) and returns the original plaintext. The problem is I can't figure out how to get the hex string back into a form that CryptoJS.AES.decrypt
will accept, and I can't find anywhere in the documentation where it actually explains how to do it. Maybe I overlooked something. Please help.
Solution 1:[1]
CryptoJS uses the WordArray
data type internally and provides encoders for conversion. If you want to convert a hex encoded string into a WordArray
, this is possible with the Hex encoder as follows:
CryptoJS.enc.Hex.parse(<your hex encoded string>)
or the other way around
<your WordArray>.toString(CryptoJS.enc.Hex)
or for short
<your WordArray>.toString()
Moreover, CryptoJS.AES.encrypt()
returns a CipherParams
object that encapsulates ciphertext and salt, among other things. This CipherParams
object is to be passed to CryptoJS.AES.decrypt()
for decryption.
With this, what you want can be implemented as follows:
function EncryptAES(text, key) {
var encrypted = CryptoJS.AES.encrypt(text, key);
return {ciphertext: encrypted.ciphertext.toString(), salt: encrypted.salt.toString()}
}
function DecryptAES(ciphertext, salt, key){
var decrypted = CryptoJS.AES.decrypt({ciphertext:CryptoJS.enc.Hex.parse(ciphertext), salt:CryptoJS.enc.Hex.parse(salt)}, key);
return decrypted;
}
var {ciphertext, salt} = EncryptAES('The quick brown fox jumps over the lazy dog', 'my passphrase');
console.log('Ciphertext (hex): ', ciphertext);
console.log('Salt (hex): ', salt);
var decrypted = DecryptAES(ciphertext, salt, 'my passphrase');
console.log('Decrypted: ', decrypted.toString(CryptoJS.enc.Utf8));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
However, there is an easier way to handle salt and ciphertext. For a CipherParams
object, .toString()
returns the data in the Base64 encoded OpenSSL format consisting of the hex encoding of Salted__
followed by the 8 bytes salt and the actual ciphertext. CryptoJS.AES.decrypt()
implicitly converts such a Base64 string into a CipherParams
object:
var encrypted = CryptoJS.AES.encrypt('The quick brown fox jumps over the lazy dog', 'my passphrase').toString();
console.log("Salt, ciphertext (OpenSSL format, Base64): ", encrypted);
var decrypted = CryptoJS.AES.decrypt(encrypted, 'my passphrase');
console.log("Decrypted: ", decrypted.toString(CryptoJS.enc.Utf8));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |