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.