AES-шифрование с помощью CryptoJS и дешифрование с помощью CodeIgniter

Я пытаюсь зашифровать имя пользователя, отправленное с помощью запроса POST на мой сервер (написано в Codeigniter 3), поэтому я шифрую на стороне клиента с помощью CryptoJS вот так:

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();

Я получаю строку длиной 64 символа, которая отправляется на мой сервер.

На моем сервере (работает CodeIgniter 3) я использую CI шифрование библиотека и я загружаю его как требуется, но когда я пытаюсь расшифровать строку, например, так:

$this->encryption->decrypt($this->input->post('encUser'), array(
'cipher' => 'aes-128',
'mode' => 'cbc',
'hmac' => FALSE,
'key' => $key
));

функция возвращает (bool)false, значит что-то пошло не так.

Что я делаю неправильно?

Примечание: не уверен, сколько мне нужно шифровать с iv потому что библиотека CI просто использует первые 16 символов из самой строки.

** РЕДАКТИРОВАТЬ **

Я создаю свой $kay (фраза) с помощью random_int polyfill и это моя функция:

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;
}

Который я звоню random_str(32);

Пример сгенерированного ключа: 1xB8oBQgXGPhcKoD0QkP1Uj4CRZ7Sy1c

** ОБНОВИТЬ **
благодаря ответу Artjom.B (и чат :) ) мы получили его, используя клиентский код его ответа и исправив код на стороне сервера так:

$user = $this->encryption->decrypt(base64_decode($this->input->post('encUser')), array(
'cipher' => 'aes-256',
'mode' => 'cbc',
'hmac' => FALSE,
'key' => $key
));

и теперь все работает.

0

Решение

В CryptoJS, если key является строкой, то будет предполагать, что key на самом деле пароль, генерирует случайную соль и получает фактический ключ и IV из пароля + соли (это делается в OpenSSL-совместимом способе через EVP_BytesToKey).

Библиотека шифрования CodeIgniter не поддерживает этот тип получения ключей. Вам придется либо изменить свой код CryptoJS, чтобы передать проанализированный WordArray:

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);

Поскольку IV написан перед зашифрованным текстом, CodeIgniter должен правильно его прочитать, и его не нужно указывать явно. Удостоверься что key правильно закодирован как Hex или Base64, потому что двоичное кодирование не работает правильно в JavaScript. Также на стороне PHP зашифрованный текст должен быть декодирован из Base64.

Вы также можете реализовать EVP_BytesToKey в PHP, как я показал Вот.

0

Другие решения

Других решений пока нет …