Шифрование AES с помощью CryptoJS и PHP - PullRequest
0 голосов
/ 27 апреля 2018

Я хочу реализовать шифрование AES с использованием JavaScript. Используется AES CBC Mode. Мне удалось сделать это на PHP. Похоже:

 public function encrypt($value) {
        if (empty($value)) {
          return $value;
        }
        $value = Unicode::convertToUtf8($value, 'UTF-8');
        if ($key = $this->getEncryptionKey()) {
          // Generates from key 1st 16 bytes.
          $iv = mb_substr($key, 0, 16);
          //encrypt message with key
          $message = openssl_encrypt($value, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
          return base64_encode($message);
        }
    }

    public function getEncryptionKey() {
        $key = 'secret';
        $key = Unicode::convertToUtf8($key, 'UTF-8');

        // Make sure the key is the correct size.
        if (strlen($key) < 32) {
          $key = str_pad($key, 32, "\0");
        }

        if (strlen($key) > 32) {
          $key = mb_substr($key, 0, 32);
        }

        return $key;
    }

Если я дам $ value = retest2; это дает мне ukUCH0SvgdmM8vTqQumAVg == вывод

Я знаю, что это правильно, я пробовал это с использованием C #, но получил тот же результат. Но когда я попытался воспроизвести это с помощью JavaScript, я не смог произвести тот же вывод PHP. Ниже приведен код JavaScript, который я пробовал:

const message = utf8.encode('retest2');
const password = utf8.encode('secret').padEnd(32, '\0');
const key =  CryptoJS.enc.Hex.parse(password);
const iv =  CryptoJS.enc.Hex.parse(password.substring(0, 16));

const encrypted = CryptoJS.AES.encrypt(message, key, {
    iv: iv
});
console.log(btoa(encrypted.toString()));

Используя то же значение, я получаю dzd4bjNwenduQT09 . Я также читал другие подобные вопросы, заданные здесь на ту же тему, но я не могу понять, где я иду не так? Спасибо!

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Как сказал @symcbean,

Вы не должны использовать ключ или данные, полученные из него, в качестве вашего вектор инициализации.

Полагаю, у вас нет выбора, и вы должны использовать ключ или данные, полученные из него, в качестве вектора инициализации.

Несколько месяцев назад у меня была точно такая же ситуация, и я сделал что-то подобное,

const message = 'retest2';
let password = 'secret';
if (password.length < 32) {
    password = password.padEnd(32, '\0');
}
const iv = CryptoJS.enc.Utf8.parse(password.substring(0, 16));
password = CryptoJS.enc.Utf8.parse(password);
const encrypted = CryptoJS.AES.encrypt((message), (password), {
    iv: iv
});
console.log(CryptoJS.enc.Base64.stringify(encrypted.ciphertext));
0 голосов
/ 27 апреля 2018

Это должны быть комментарии, но пространство ограничено ....

Вы не должны использовать ключ или данные, полученные из него, в качестве вектора инициализации.

Я знаю, что это правильно, я тоже пробовал использовать C #

Вы должны были показать нам код.

Ваш вызов openssl вызывает функцию получения ключа для создания (лучше?) Ключа шифрования из данных, которые вы передаете в третьем параметре. OTOH, в crypto.js нет неявного получения ключа .

...