php - AES encryption with CryptoJS and decryption with CodeIgniter
Get the solution ↓↓↓I'm trying to encrypt a username sent via POST request to my server (written in Codeigniter 3), so I'm encrypting on the client side with CryptoJS like so:
var user = $('.user').val();
var key = "<? echo($key);?>"; //$key is created on the server side
var encUser = CryptoJS.AES.encrypt(user, key, {
mode: CryptoJS.mode.CBC
}).toString();
I get a fine looking 64 characters long string, which I send to my server.
On my server (running CodeIgniter 3) I am using the CI encryption library and I'm loading it as required, but when I try to decrypt the string like so:
$this->encryption->decrypt($this->input->post('encUser'), array(
'cipher' => 'aes-128',
'mode' => 'cbc',
'hmac' => FALSE,
'key' => $key
));
the function returns(bool)false
, meaning something went wrong.
What am I doing wrong?
Note: not sure how much I need to encrypt withiv
because the CI library just uses the first 16 chars from the string itself.
** EDIT **
I'm creating my$kay
(passphrase) with the help of the random_int polyfill and this is my function:
private function random_str($length, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
$str = '';
$max = mb_strlen($keyspace, '8bit') - 1;
for ($i = 0; $i < $length; ++$i) {
$str .= $keyspace[random_int(0, $max)];
}
return $str;
}
Which i am callingrandom_str(32)
;
Example generated key:1xB8oBQgXGPhcKoD0QkP1Uj4CRZ7Sy1c
** UPDATE **
thanks to Artjom.B's answer(and chat:)
) we got it working, using his answer's client side code and fixing the server side code to be:
$user = $this->encryption->decrypt(base64_decode($this->input->post('encUser')), array(
'cipher' => 'aes-256',
'mode' => 'cbc',
'hmac' => FALSE,
'key' => $key
));
and now everything is working.
Answer
Solution:
In CryptoJS, ifkey
is a string, then it will assume thatkey
is actually a password, generate a random salt and derive the actual key and IV from password+salt (this is done in an OpenSSL-compatible way throughEVP_BytesToKey
).
CodeIgniter's Encryption library doesn't support this type of key derivation. You will either have to change your CryptoJS code to pass in a parsedWordArray
:
var key = CryptoJS.enc.Hex.parse("<? echo(bin2hex($key));?>");
var iv = CryptoJS.lib.WordArray.random(128/8);
var encUser = CryptoJS.AES.encrypt(user, key, {
iv: iv
}).ciphertext;
return iv.concat(encUser).toString(CryptoJS.enc.Base64);
Since the IV is written in front of the ciphertext, CodeIgniter should read it correctly and it doesn't have to be specified explicitly. Make sure thatkey
is correctly encoded as Hex or Base64, because binary encoding doesn't work in JavaScript correctly. Also, at the PHP side, the ciphertext must be decoded from Base64.
You could also implementEVP_BytesToKey
in PHP as I've shown here.
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: videoxxx
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.