1

I dealing with cryptojs and want to try a simple example with aes

var encrypted = CryptoJS.AES.encrypt("TEST_TEXT", '9021D105A446', {
  mode: CryptoJS.mode.ECB,
  padding: CryptoJS.pad.Pkcs7
});

var decrypt = CryptoJS.AES.decrypt(encrypted, '9021D105A446', {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
});
console.log(decrypt.toString(CryptoJS.enc.Utf8));//Yeah! TEST_TEXT output as expected

Now I give a try with encrypted in base64, but not output as expected

 var encryptedText = encrypted.ciphertext.toString(CryptoJS.enc.Base64)
 var encrypted2 = CryptoJS.enc.Base64.parse(encryptedText);
 var decrypt2 = CryptoJS.AES.decrypt(encrypted2, '9021D105A446', {
     mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
   });
console.log(decrypt2.toString(CryptoJS.enc.Utf8));// Ops! empty output

Do you know something went wrong with decryption in 2nd example?

Another question, every I run example 1, the encryptedText was difference from previous running. Is this normal behavior?

Fiddle update : https://jsfiddle.net/n6wL9a40/

Ryo
  • 995
  • 2
  • 25
  • 41

2 Answers2

3

You don't need to convert encrypted value to base64, encrypted.toString() returns base64 value.

var base64Value = encrypted.toString();
// base64Value is U2FsdGVkX19s42BDpx8A9I265vm+zGKSk8nEbQwNjfw=
var encryptedText = CryptoJS.enc.Base64.parse(base64Value)
var encrypted2 = encryptedText.toString(CryptoJS.enc.Base64);
var decrypt2 = CryptoJS.AES.decrypt(encrypted2, '9021D105A446', {
 mode: CryptoJS.mode.ECB,
 padding: CryptoJS.pad.Pkcs7
});

console.log(decrypt2.toString(CryptoJS.enc.Utf8));// TEST_TEXT
2

First, actually CryptoJS.enc.Base64.parse(encryptedText) doesn't give you back a Base64 string, but an object, you should use it with toString like this: CryptoJS.enc.Base64.parse(encryptedText).toString() to get back your original string that was encoded in Base64

But the real problem is that you use the wrong part of the encrypted object (see linked fiddle, trying to decrypt .ciphertext won't work, because ciphertext is just the last part of the encrypted result needed for decryption, first part is missing). And additionally, there is no need to convert your output to Base64 at all, because it's already in Base64!

console.log(encrypted.toString()); //will already be Base64

See all this in an updated fiddle: https://jsfiddle.net/gqkcvjxo/

EDIT: For your other question I quote the docs:

CryptoJS supports AES-128, AES-192, and AES-256. It will pick the variant by the size of the key you pass in. If you use a passphrase, then it will generate a 256-bit key

You can generate a key for AES-128 by using a pass of length 16 (128/8), you'll see in the fiddle that it works, the encrypted text length is halved.

var pass = 'abcdefghijklmnop'; //must be length 16 (because 128/8)
var key =  CryptoJS.enc.Utf8.parse(pass);

Updated fiddle: https://jsfiddle.net/o3975jtd/3/

To answer your other question, the encrypted text is not the same each time in first version because of the generated iv (see explanation here). By using a key with AES-128 in ECB mode, the iv is not automatically generated and comes undefined (apparently, when trying to specify one, nothing changes, probably because it's not used as told in the explanation link)

Kaddath
  • 5,933
  • 1
  • 9
  • 23
  • 1
    I have one more question could you help? By default seem Cryptojs using `AES-256`, how can I set it to `aes-128` – Ryo Sep 16 '19 at 10:12