13

I am encrypting some data using CryptoJS and comparing it to an online tool and I am not getting the same result. In fact the result from CryptoJS in not decryptable with the tool.

I am trying to encrypt in AES-256-CBC with the following parameters:

text = '111222333'
iv = 'I8zyA4lVhMCaJ5Kg'
key = '6fa979f20126cb08aa645a8f495f6d85'

Here's my code:

let text = '111222333';

aesEncrypt(data) {
    let key = '6fa979f20126cb08aa645a8f495f6d85';    //length 32
    let iv = 'I8zyA4lVhMCaJ5Kg';                     //length 16
    let cipher = CryptoJS.AES.encrypt(data, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    return cipher.toString();
}

aesEncrypt(text);

The resulting encrypted string is U2FsdGVkX1+f3UywYmIdtb50bzdxASRCSqB00OijOb0= while the one obtained with the online tool is B6AeMHPHkEe7/KHsZ6TW/Q==. Why are they different, I seem to be using the same parameters?

My plan in using CryptoJS is to encrypt some data client side and then be able to decrypt it server side, if needed. But the differences in both encrypted values is stopping me to do so.

Alex Blais
  • 145
  • 1
  • 2
  • 6

2 Answers2

20

How 'bout encoding your data as UTF-8. Just like the "online tool" is doing.

Use CryptoJS.enc.Utf8.parse to achieve what I'm saying.

aesEncrypt (data) {
   const key = '6fa979f20126cb08aa645a8f495f6d85'
   const iv = 'I8zyA4lVhMCaJ5Kg'
   
   const cipher = CryptoJS.AES.encrypt(data, CryptoJS.enc.Utf8.parse(key), {
       iv: CryptoJS.enc.Utf8.parse(iv), // parse the IV 
       padding: CryptoJS.pad.Pkcs7,
       mode: CryptoJS.mode.CBC
   })
   
   // e.g. B6AeMHPHkEe7/KHsZ6TW/Q==
   return cipher.toString()
}

Code snippet using CryptoJS.

function aesEncrypt (data) {
   const key = '6fa979f20126cb08aa645a8f495f6d85'
   const iv = 'I8zyA4lVhMCaJ5Kg'
   const cipher = CryptoJS.AES.encrypt(data, CryptoJS.enc.Utf8.parse(key), {
       iv: CryptoJS.enc.Utf8.parse(iv),
       padding: CryptoJS.pad.Pkcs7,
       mode: CryptoJS.mode.CBC
   })

   return cipher.toString()
}

// e.g. B6AeMHPHkEe7/KHsZ6TW/Q==
console.log(aesEncrypt('111222333'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>

Working Stackblitz example

Max
  • 374
  • 1
  • 4
  • 10
weegee
  • 3,256
  • 2
  • 18
  • 32
  • That definitely solved the problem, thank you. Do you have any idea how the key and iv are handled if the UTF8.parse is not specified? – Alex Blais Aug 08 '19 at 17:05
  • 1
    UTF8 parsing is specified in every language. They are handled according to the encoding your text editor is using (or how you encoded). UTF8 is a standard one so this can be used in java or anywhere else and you'll get the same result. @AlexBlais – weegee Aug 08 '19 at 17:21
  • I meant, CryptoJS doesn't seem to default to UTF8 since it has to be specified. My guess would have been it defaulted to base64 or something like that. Is that correct? – Alex Blais Aug 08 '19 at 17:29
  • 1
    @AlexBlais no it's your text editor and you can't expect a library to assume an encoding. It seriously affects the encryption. You just saw :') – weegee Aug 08 '19 at 17:31
  • How to do decrypt? – Nitin Karale Dec 17 '20 at 12:19
  • @NitinKarale there's an example for decryption in the ciphers section of the [link I have linked in the answer body](https://cryptojs.gitbook.io/docs/#ciphers) – weegee Jan 21 '21 at 10:21
0

Based on WeeGee's answer, added this function aesDecrypt in order to decrypt back the encrypted text and return the string in UTF8. @WeeGee you saved my day.

const key = CryptoJS.enc.Utf8.parse('6fa979f20126cb08aa645a8f495f6d85');
const iv = CryptoJS.enc.Utf8.parse('I8zyA4lVhMCaJ5Kg');

const text = '111222333';

function aesEncrypt(data) {
    let cipher = CryptoJS.AES.encrypt(data, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    return cipher.toString();
}

function aesDecrypt(data) {
  let cipher = CryptoJS.AES.decrypt(data, key, {
      iv: iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
  });
  return cipher.toString(CryptoJS.enc.Utf8);
}

const encryptedText = aesEncrypt(text);
const decryptedText = aesDecrypt(encryptedText);

console.log('Before Encrypt - ' + text);
console.log('Encrypted Text - ' + encryptedText);
console.log('Decrypted Text - ' + decryptedText);

Output

Before Encrypt - 111222333 
Encrypted Text - B6AeMHPHkEe7/KHsZ6TW/Q==
Decrypted Text - 111222333
latt
  • 73
  • 7