crytpojs и openssl — разные выходы aes

#javascript #php #openssl #cryptography #cryptojs

#javascript #php #openssl #криптография #cryptojs

Вопрос:

Я пытаюсь получить тот же результат шифрования AES в PHP и Javascript

PHP-код:

 <?php
$rawKey = openssl_random_pseudo_bytes(32);
$iv = substr($rawKey, 16, 16);
$data = "5295760474330638";
$encryptedData = openssl_encrypt($data, "AES-128-CBC", $rawKey, OPENSSL_RAW_DATA, $iv);
echo base64_encode($rawKey); // CfOXpWTBF9mNcs7qSBw62OJpp U/l/fu/YLh5aOXpXY=
echo base64_encode($iv); // 4mmn5T X9 79guHlo5eldg==
echo base64_encode($encryptedData); // 3QQWLw7Q Ff0Gz50XGsGORsOMWh9oeBiYprPr3/vl I=
 

Код Javascript:

 encrypt () {
    const key = this.CryptoJS.enc.Base64.parse('CfOXpWTBF9mNcs7qSBw62OJpp U/l/fu/YLh5aOXpXY=');
    const iv = this.CryptoJS.enc.Base64.parse('4mmn5T X9 79guHlo5eldg==');
    const data = '5295760474330638';
    const encrypted: any = this.CryptoJS.AES.encrypt(data, key, {
      mode: this.CryptoJS.mode.CBC,
      iv: iv
    });
    console.log(encrypted.ciphertext.toString(this.CryptoJS.enc.Base64)); 
    // QivkpDkujSt0JHAMwnENe6Qlkvgb8 3ddu7AcP401aM=
}
 

Почему я получаю разные выходы, хотя ключ и iv одинаковы?

Комментарии:

1. Просто используйте AES-256-CBC в своем PHP-коде. В коде CryptoJS применяется 32-байтовый ключ и, следовательно, AES-256. Оба также должны использоваться в коде PHP для создания одного и того же зашифрованного текста! Примечание: В отличие от кода CryptoJS, где длина ключа определяет вариант AES (например, 32-байтовый ключ определяет AES-256), в коде PHP вариант AES должен быть указан явно (например, AES-256-CBC). Слишком короткие ключи дополняются значениями 0, слишком длинные ключи просто усекаются.

2. Это работает, спасибо @Topaco. Кстати, можно ли не изменять код PHP и вместо этого принудительно использовать AES-128 в Crypto js с помощью этого ключа?

3. На самом деле я уже объяснял это: поскольку AES-128-CBC указан в коде PHP, для фактического ключа используются только первые 16 байт из 32-байтового ключа $rawKey . В качестве IV применяются последние 16 байтов $rawKey . В коде CryptoJS должны использоваться один и тот же ключ и IV, например const key2 = CryptoJS.lib.WordArray.create(key.words.slice(0, 4)); , и const iv2 = CryptoJS.lib.WordArray.create(key.words.slice(4, 4 4)); . Здесь key уже определен ключ (соответствующий $rawKey ). Теперь используйте key2 и iv2 в качестве ключа и IV для шифрования, тогда вы получите результат PHP-кода.