2016-06-05 5 views
0

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

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 encryption и я загружаю его по мере необходимости, но когда я пытаюсь расшифровать строку следующим образом:

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

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

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

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

** EDIT **

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

private function random_str($length, $keyspace = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') 
{ 
    $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

** UPDATE ** благодаря ответу Artjom.B (и чат :)) мы получили его работы, используя код на стороне клиента, его ответ и фиксируя на стороне сервера код be:

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

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

+0

@ RyanVincent, но как я могу зашифровать без ключа? – FireBrand

+0

Дело в том, что я не могу использовать 'iv' на стороне сервера, lib просто берет первые 16 символов из строки и использует это как' iv' – FireBrand

ответ

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, как я показал here.

+0

Использование 'base64_decode()' на зашифрованном username дал мне это: ' % ؋ { ? {! i v w Kse 2X c ; * A;' и функция дешифрования вернулась ' false' again – FireBrand

+1

Закодировали ли ключ '$ key 'в Hex для JavaScript, но использовали дефиницию« $ key »для дешифрования? –

+0

Я использовал его raw, я попытался разобрать его сейчас, но я не могу правильно его разобрать на сервере по какой-то причине – FireBrand

Смежные вопросы