I receive a base64 encoded string. The first 16 bytes are the IV. I need to extract them before I decrypt with CryptoJS.
I am failing to split data from CryptoJS.enc.Base64.parse
In a nutshell, please help me fill this:
/*
* ivAndcipheredDataBase64: first 16 bytes are iv the rest is the cipheredData
*/
function decipherData(ivAndcipheredDataBase64, key) {
var ivAndCipheredDataBytes = CryptoJS.enc.Base64.parse(ivAndcipheredDataBase64);
var iv = // What do I put here to get cipheredIVAndDataBytes[0:16]
var cipheredData = // What do I put here to get cipheredIVAndDataBytes[16:len(cipheredIVAndDataBytes)]
var plainDataBytes = CryptoJS.AES.decrypt({ ciphertext: cipheredData }, key, {
iv: iv
});
return plainDataBytes.toString(CryptoJS.enc.Utf8)
}
Thanks, I am having trouble to know the type returned by CryptoJS.enc.Base64.parse
, the documentation says WordArray object
but i am not sure how to deal with that
A WordArray
contains an array (called words
) of words. Each word in words
contains 4 bytes of data. The number of significant data bytes is stored in sigBytes
. Example:
var data = CryptoJS.lib.WordArray.create([0x6a757374, 0x20612074, 0x6573746d, 0x65737361, 0x67650123], 18); // a WordArray with 5*4=20 bytes; the last 2 bytes are ignored because sigBytes = 18
console.log(data.toString())
console.log(data.toString(CryptoJS.enc.Utf8))
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js"></script>
If the data is a multiple of 4 bytes, sigBytes
does not need to be specified. All bytes are then taken into account.
To solve your problem, you need to create a WordArray
for each IV and ciphertext with CryptoJS.lib.WordArray.create()
and slice IV and ciphertext from the words
array of the WordArray
of the concatenated data:
...
var ivAndCipheredDataBytes = CryptoJS.enc.Base64.parse(ivAndcipheredDataBase64);
var iv = CryptoJS.lib.WordArray.create(ivAndCipheredDataBytes.words.slice(0, 4)); // iv: first 4 words = 16 bytes
var ct = CryptoJS.lib.WordArray.create(ivAndCipheredDataBytes.words.slice(4)); // ciphertext: rest
...
Since both IV (for AES 16 bytes) and ciphertext (for AES/CBC a multiple of the block size of 16 bytes) are multiples of 4 bytes, the specification of sigBytes
is not required.