3

I am trying to Encrypt some text from CryptoJS and decrypt it with Phalcon.

I encrypt as follows,

CryptoJS.AES.encrypt("MyText", 'key123');

Now to compare I encrypt the same value with Phalcon as,

$this->crypt = new Crypt();
$this->crypt->encrypt("MyText", 'key123');

Now the values I get from JS and PHP are different.

Phalcon default encryption is AES and so do in CryptoJS.

Please help me on this. I want to have the same value in both sides.

masterFly
  • 1,072
  • 12
  • 24
  • Are your encryption settings the same on both the JS and Phalcon side? (I had this problem once and this question helped me: http://stackoverflow.com/questions/16600509/aes-encrypt-in-cryptojs-and-decrypt-in-coldfusion) – Timothy Jun 06 '16 at 07:04
  • Hi @Timothy, first I was on defaults. But then changed it to have specific values, like in the link you gave. Still cannot make it work. – masterFly Jun 06 '16 at 07:43

1 Answers1

3

The default cipher in Phalcon is Rijndael-256, which is not supported by CryptoJS. It would be necessary to change that to Rijndael-128 (AES). It's also necessary to use some kind of padding mode in Phalcon in order to be able to encrypt arbitrary binary data.

$keyHex = "0102030405060708090a0b0c0d0e0f";

$this->crypt = new Crypt();
$this->crypt->setPadding($this->crypt->PADDING_PKCS7);
$this->crypt->setCipher("rijndael-128");

// encryption
$ct = base64_encode($this->crypt->encrypt("MyText", hex2bin($keyHex)));

// decryption
var_dump($this->crypt->decrypt(base64_decode($ct), hex2bin($keyHex)));

The 128 bit initialization vector is prefixed to the ciphertext, so it has to be done in the same way in CryptoJS.

var key = CryptoJS.enc.Hex.parse("0102030405060708090a0b0c0d0e0f");
var iv = CryptoJS.lib.WordArray.random(128/8);
var ct = CryptoJS.AES.encrypt("MyText", key, {
    iv: iv
}).ciphertext;
return iv.concat(ct).toString(CryptoJS.enc.Base64);

Things to note:

  • The key must be randomly generated. This is an example 16 byte key (32 hexits) and it has to have a specific length. AES supports key sizes of 16, 24 and 32 bytes (32, 48, 64 hexits).

  • The IV is generated randomly for every encryption, so it is not possible to encrypt the same text with the same key in CryptoJS and Phalcon to check compatibility. It is necessary to encrypt in one and decrypt in the other.

  • Symmetric encryption without authentication can be very dangerous. It might be possible to mount a padding-oracle attack in your case. A common way to add authentication is to run a message authentication code over the IV + ciphertext with a separate key. HMAC-SHA256 with an encrypt-then-MAC scheme is a strong choice in that regard.

  • If the "key" is passed as a string to CryptoJS.AES.encrypt, then it invokes an OpenSSL compatible key derivation function (EVP_BytesToKey). The given "key" is assumed to be a password, therefore it generates a random salt, and derives the actual key and IV from those two.

  • Phalcon uses mcrypt, which is abandonware and has many bugs.

Community
  • 1
  • 1
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • I don't actually have Phalcon running, so this code is just created from reading its [source code](https://github.com/phalcon/cphalcon/blob/phalcon-v2.0.13/phalcon/crypt.zep). – Artjom B. Jun 06 '16 at 07:53
  • Hi @Artjom B., Thank for the response. Could you please explain me this line? `var ct = CryptoJS.AES.encrypt("MyText", key, { iv: iv }).ciphertext;` – masterFly Jun 06 '16 at 08:22
  • Phalcon handles the IV for you, but CryptoJS doesn't, so it is necessary to provide a specific IV. The result of `CryptoJS.AES.encrypt(...)` is a `CipherParams` object which contains a lot of information in addition to the actual ciphertext. Here you only need the ciphertext, so you retrieve only that. – Artjom B. Jun 06 '16 at 08:37
  • Thank you @Artjom B.. Now I am getting it. What is the value for `ciphertext`. That variable is confusing me. Thanks in advance – masterFly Jun 06 '16 at 09:29
  • `CryptoJS.AES.encrypt(...).ciphertext` is a `WordArray` which is the internal representation of binary data in CryptoJS. – Artjom B. Jun 06 '16 at 09:32