Моя проблема в следующем:
У меня есть PHP-скрипт, который отвечает за шифрование строки с использованием шифрования AES-256-CBC. Этот скрипт использует openssl lib и возвращает результат X.
<?php
class AES
{
const PRIVATE_KEY = 'abcdefghijklmnnoabcdefghijklmnno';
const ENCRYPT_METHOD = 'aes-256-cbc';
const VECTOR = 'abcdefghijklmnno';
public function encryptData($data)
{
while(strlen($data) < 16) $data .= "\0";
return openssl_encrypt($data, self::ENCRYPT_METHOD, self::PRIVATE_KEY, OPENSSL_ZERO_PADDING, self::VECTOR);
}
public function encryptDataL($data)
{
return openssl_encrypt($data, self::ENCRYPT_METHOD, self::PRIVATE_KEY, 0, self::VECTOR);
}
public function decryptData($data)
{
return openssl_decrypt($data, self::ENCRYPT_METHOD, self::PRIVATE_KEY, OPENSSL_ZERO_PADDING, self::VECTOR);
}
}
$aes = new AES();
echo $aes->encryptData("abcdefghijkl");
echo "\n";
echo $aes->encryptDataL("{\"REQUEST\": [{\"MSISDN\": \"32156489721\",\"IDPRODUCT\": 123,\"IDOPERATOR\": 12345,\"OUTPUTFORMAT\": \"JSON\"}],\"OUTPUTFORMAT\": \"json\"}");
?>
Когда я запускаю JS-скрипт, отвечающий за то же самое, но с использованием Crypto lib, полученный результат отличается от предыдущего X.
const crypto = require('crypto');
const cipher = crypto.createCipheriv('aes-256-cbc', 'abcdefghijklmnnoabcdefghijklmnno', 'abcdefghijklmnno');
let crypted = cipher.update(data, 'utf8', 'base64');
crypted += cipher.final('base64');
Результаты скриптов различаются, хотя теоретически шифрование должно быть одинаковым.
Пример возврата выглядит следующим образом:
Для скрипта php: ввод -> ^ y3Hk3JKGGgA вывод -> eTqD5Op389QS / TOoui5kAQ ==
Для сценария js: ввод -> ^ y3Hk3JKGGgA вывод -> HHfskOE1N + QxdGt9MTai5A ==
Желаемый результат - сценарий PHP, но мне нужно запустить код на JS, может ли кто-нибудь объяснить мне, что я делаю неправильно?
Я пробовал разные способы выполнить метод createCipheriv, но все они возвращают один и тот же результат (отличный от того, что мне нужно, то есть результат, полученный с помощью сценария PHP)
Заранее спасибо.
1 ответ
Спасибо, ребята, за попытку помочь, действительно, я разместил вопрос без некоторой информации (на самом деле, когда вопрос был задан, у меня не было всей необходимой информации).
Но размещаю здесь некоторые факты и решение, встреченное для моего случая.
Разные результаты в приведенных выше случаях случаются только для первой функции PHP ("encryptData"), ответственной за шифрование небольших текстов. Второй, отвечающий за шифрование больших текстов (более 16 бит), отлично работал как в PHP, так и в JS скриптах.
Решение, с которым я столкнулся, заключалось в том, чтобы самостоятельно сделать отступы, необходимые для алгоритма AES-256. Функция заполнения, предоставляемая Crypto lib, не работала, по крайней мере, в моем случае.
Поэтому я отключил заполнение в моем классе cypher и убедился, что данные, отправленные для шифрования, были заполнены правильно до тех пор, пока длина не станет кратной 16. Конечный код приведен ниже.
encryptWithAES256(data) {
// added padding until data length is multiple of 16
let paddedData = data;
while (paddedData.length % 16 !== 0) {
paddedData += '\0';
}
// ciphers data
const cipher = crypto.createCipheriv('aes-256-cbc', encodeKey, IV);
cipher.setAutoPadding(false);
let crypted = cipher.update(paddedData, 'utf8', 'base64');
crypted += cipher.final('base64');
return crypted;
}
Похожие вопросы
Новые вопросы
php
PHP — это открытый, мультипарадигмальный, динамически типизированный и интерпретируемый язык сценариев, изначально разработанный для веб-разработки на стороне сервера. Используйте этот тег для вопросов о программировании на языке PHP.