PHP openssl_decrypt не дает такие же результаты, как онлайн-инструменты - PullRequest
1 голос
/ 31 октября 2019

Используя онлайн-инструмент шифрования / дешифрования, используя DES-ECB, я могу зашифровать 8-значное шестнадцатеричное число с помощью 8-значного шестнадцатеричного ключа, в результате чего получается 8-значный шестнадцатеричный результат. Я могу расшифровать результат из 8 цифр с помощью того же ключа и получить зашифрованные исходные данные.

Однако я не могу воспроизвести это локально с помощью PHP. Оказывается, зашифрованный результат, который я получаю в Интернете, - это первые 8 из 16 фактически произведенных цифр. Нет проблем ... Но когда я пытаюсь расшифровать локально с помощью PHP, мне нужны все 16 цифр, чтобы получить исходные данные.

Как я могу расшифровать только с 8 цифрами и при этом получить исходные данные,как это делает онлайн-инструмент?

Онлайн-результаты:

Шифрование:

$data = '03 67 A6 7F C2 00 0A DB';
$key = '00 F2 83 CD BA 41 6F FF';
$result = '8b be 0f 3b ae 92 56 07';

Проверка: http://des.online -domain-tools.com / link / 1b40d6agZYE0TFR5sM/

Расшифровка:

$data = '8b be 0f 3b ae 92 56 07';
$key = '00 F2 83 CD BA 41 6F FF';
$result = '03 67 A6 7F C2 00 0A DB';

Проверка: http://des.online -domain-tools.com / link / 1b40e05gD5TNgMb72h /

LocalТест PHP:

$enc = openssl_encrypt( hex2bin('0367A67FC2000ADB'), 'DES-ECB', hex2bin('00F283CDBA416FFF'), 1);

bin2hex($enc) приводит к 8bbe0f3bae9256071da486ee680f8449

Если я расшифрую только первые 8 шестнадцатеричных цифр, я не получу те же результаты, что и с онлайн-инструментом:

$dec = openssl_decrypt( hex2bin('8bbe0f3bae925607'), 'DES-ECB', hex2bin('00F283CDBA416FFF'), 1);

bin2hex($dec) приводит к нулю (или ложь, если мы не преобразуем в шестнадцатеричный код)

Но если я введу 16-значный шестнадцатеричный код в качестве зашифрованных данных, я получуправильный результат:

$dec = openssl_decrypt( hex2bin('8bbe0f3bae9256071da486ee680f8449'), 'DES-ECB', hex2bin('00F283CDBA416FFF'), 1);

bin2hex($dec) приводит к 0367A67FC2000ADB

Это имеет смысл для меня ... но мне нужно иметь возможность получить этот результат только из 8-значного гекса, каконлайн инструмент делает. Что мне нужно сделать, чтобы это стало возможным?

1 Ответ

1 голос
/ 31 октября 2019

Причиной различия является отступ . Блочный шифр допускает только шифрование данных, длина которых соответствует целому кратному размеру блока (8 байтов в случае DES). Заполнение обеспечивает выполнение этого условия путем добавления данных в соответствии с определенной логикой.

Существуют различные типы заполнения. openssl_encrypt / openssl_decrypt использует PKCS7-заполнение по по умолчанию , онлайн-инструмент нулевой обивка .

PKCS7-дополнение всегда будет добавлять данные в открытый текст, даже если открытый текст уже имеет длину, кратную целому размеру блока. В этом случае добавляется полный блок ( детали ). По этой причине опубликованный зашифрованный текст, сгенерированный с openssl_encrypt, имеет длину 2 блока (16 байт) для открытого текста с длиной 1 блок (8 байт).

В отличие от заполнения PKCS7, нулевойВариант заполнения, используемый онлайн-инструментом, не добавляет никаких данных, если длина открытого текста уже кратна размеру блока. По этой причине опубликованный зашифрованный текст, созданный с помощью онлайн-инструмента, имеет длину 1 блок (8 байт) для открытого текста длиной 1 блок (8 байт).

openssl_encrypt / openssl_decryptне поддерживает заполнение нулями. Чтобы зашифрованный текст openssl_encrypt совпадал с шифром онлайн-инструмента, заполнение PKCS7 должно быть отключено, а вариант заполнения нулями, используемый онлайн-инструментом, должен быть реализован вручную . Отключение заполнения выполняется с помощью флага OPENSSL_ZERO_PADDING, который должен быть установлен четвертым параметром. Примечание : название флага вводит в заблуждение: этот флаг не включает заполнение нулями, а только отключает заполнение PKCS7. Это означает, что вариант онлайн-инструмента с нулевым заполнением все еще должен быть реализован вручную. Кроме того: в текущем коде значение 1 передается в четвертом параметре, который соответствует флагу OPENSSL_RAW_DATA. Чтобы установить оба флажка, значение 1 должно поэтому быть заменено на OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING.

Для открытых текстов, длина которых уже соответствует целому кратному размеру блока, как отключенному дополнению PKCS7, так и заполнению нулямивариант, используемый онлайн-инструментом, не добавляет никаких дополнительных данных, так что шифротексты совпадают. В этом случае ручная реализация варианта заполнения нулями, используемого онлайн-инструментом, не требуется.

Последнее замечание по безопасности: DES небезопасно. Сегодняшний стандарт AES . ЕЦБ также небезопасен. Более безопасными режимами являются, например, CBC или GCM.

...