Зашифруйте с помощью AES с помощью phpseclib и расшифруйте с помощью CryptoJS

Я пытаюсь зашифровать строку с помощью phpseclib AES в режиме CBC (по умолчанию для библиотеки):

$cipher = new Crypt_AES();
$cipher->setKey('abcdefghijklmnop');
$cipher->setIV(crypt_random_string($cipher->getBlockLength() >> 3));
$cipher->encrypt("hello world")

Затем мне нужно расшифровать nodejs с помощью CryptoJS или аналогичного ... Я пробовал разные библиотеки, но пока не повезло. Я предполагаю, что проблема связана с тем, что закодированный вывод отличается от каждой библиотеки.

Есть ли у кого-нибудь рабочий пример того, как реализовать этот сценарий взаимодействия?

Можно использовать другую библиотеку, такую ​​как Crypto. Пример вывода Base64: MF9lCR4DaW1R0adIe03VEw==

Итак, идея состоит в следующем:

var helloWorld = CryptoJS.AES.decrypt("MF9lCR4DaW1R0adIe03VEw==", key).toString();

person Roberto14    schedule 02.03.2016    source источник
comment
Зачем вам использовать стороннюю криптографическую библиотеку в узле, если есть встроенная и более быстрая?   -  person mscdex    schedule 02.03.2016
comment
Можете ли вы привести пример зашифрованного вывода (например, в шестнадцатеричном или base64)?   -  person mscdex    schedule 02.03.2016
comment
@mscdex только что обновил вопрос, добавив несколько примеров, как вы просили. Кстати, криптобиблиотека узла - тоже вариант.   -  person Roberto14    schedule 02.03.2016
comment
Разве вам не нужен IV для расшифровки?   -  person robertklep    schedule 02.03.2016


Ответы (1)


Во время расшифровки вам понадобится сгенерированный ранее IV. Это не обязательно должно быть секретом, но оно должно быть непредсказуемым (как в вашем случае). Вы можете отправить его вместе с зашифрованным текстом. Распространенный способ - добавить его к зашифрованному тексту и отрезать его во время дешифрования.

CryptoJS поддерживает два типа шифрования. Если вы передадите ключ в виде строки, он будет использовать функцию деривации ключа OpenSSL для получения нового ключа с солью. Вы этого не хотите, потому что вы используете явный ключ. Для этого вам необходимо передать ключ как WordArray (собственная двоичная структура данных CryptoJS). Кроме того, ожидается, что зашифрованный текст будет либо строкой в ​​формате OpenSSL, либо объектом CipherParams:

var message = CryptoJS.AES.decrypt({
    ciphertext: CryptoJS.enc.Base64.parse("MF9lCR4DaW1R0adIe03VEw==")
}, CryptoJS.enc.Utf8.parse('abcdefghijklmnop'), {
    iv: iv // retrieve the IV somehow
}).toString(CryptoJS.enc.Utf8);
person Artjom B.    schedule 02.03.2016
comment
Я думал, что IV уже добавлен к зашифрованным данным (зашифрованному тексту) и будет беспрепятственно проанализирован на узле ... поэтому я не пытался установить его вручную. Спасибо за ответ! - person Roberto14; 02.03.2016
comment
Вы можете проверить это, посмотрев на длину зашифрованного текста. Base64 имеет коэффициент раздува 4/3. Это означает, что фактическая длина зашифрованного текста len(b64)*3/4-paddingChars, которая в вашем случае равна 24*3/4-2 = 18 - 2 = 16. 16 - это размер блока AES, и поскольку CBC не является потоковым режимом, он должен создать как минимум блок. Значит, IV негде быть. - person Artjom B.; 02.03.2016