Шифрование в Coldfusion, а затем расшифровка в PHP

У меня проблема с воспроизведением того же результата, полученного в PHP против Coldfusion.

В PHP шифрование таким образом:

<?php
    $key = "$224455@";
    $Valor = "TESTE";

    $base = chop(base64_encode(mcrypt_encrypt(MCRYPT_DES, $key, $Valor, MCRYPT_MODE_ECB)));     
?>

У меня есть результат:

TzwRx5Bxoa0=

В Coldfusion сделали так:

<cfset Valor = "TESTE">
<cfset Key = "$224455@">
<cfset base = Encrypt(Valor,ToBase64(Key),"DES/ECB/PKCS5Padding","BASE64")>

Результат:

qOQnhdxiIKs=

Что не дает ColdFusion той же ценности, что и PHP?

Большое Вам спасибо


person Hilso Vasques Junior    schedule 07.03.2015    source источник


Ответы (2)


(Слишком долго для комментариев)

Artjom B. уже предоставил ответ выше. Артём Б. написал

Проблема в прокладке. Расширение PHP mcrypt использует только ZeroPadding [...], вам нужно либо дополнить открытый текст в php [...], либо использовать другой шифр в ColdFusion, например «DES/ECB/NoPadding». Я рекомендую первое, потому что если вы используете NoPadding, открытый текст уже должен быть кратен размеру блока.

К сожалению, в CF сложно создать нулевой символ. Насколько я знаю, единственный работающий метод - использовать URLDecode("%00"). Если вы не можете изменить код PHP, как предложил @Artjom B., вы можете попробовать использовать функцию ниже, чтобы дополнить текст в CF. Отказ от ответственности: он только слегка протестирован (CF10), но, похоже, дал тот же результат, что и выше.

Обновление: поскольку функция CF encrypt() всегда интерпретирует ввод простого текста как строку UTF-8, вы также можете использовать charsetEncode(bytes, "utf-8") для создания нулевого символа из массива байтов с одним элементом, т.е. /эм> charsetEncode( javacast("byte[]", [0] ), "utf-8")


Пример:

Valor = nullPad("TESTE", 8);
Key = "$224455@";
result = Encrypt(Valor, ToBase64(Key), "DES/ECB/NoPadding", "BASE64");
// Result: TzwRx5Bxoa0=
WriteDump( "Encrypted Text = "& Result ); 

Функция:

/*
   Pads a string, with null bytes, to a multiple of the given block size

   @param plainText - string to pad
   @param blockSize - pad string so it is a multiple of this size
   @param encoding - charset encoding of text
*/
string function nullPad( string plainText, numeric blockSize, string encoding="UTF-8")
{
    local.newText = arguments.plainText;
    local.bytes = charsetDecode(arguments.plainText, arguments.encoding);
    local.remain = arrayLen( local.bytes ) % arguments.blockSize;

    if (local.remain neq 0) 
    {
        local.padSize = arguments.blockSize - local.remain;
        local.newText &= repeatString( urlDecode("%00"), local.padSize );
    }

    return local.newText;
}
person Leigh    schedule 08.03.2015
comment
Личное, теперь отлично работало в начальном тесте, я проведу несколько тестов позже, но я считаю, что решение то же самое. Спасибо за помощь и оперативность. Мне очень помог. Спасибо - person Hilso Vasques Junior; 08.03.2015
comment
АртёмБ. разобрался в реальной проблеме, но рад, что вышеизложенное помогло :) - person Leigh; 08.03.2015

Проблема в прокладке. Расширение PHP mcrypt использует только ZeroPadding. Это означает, что открытый текст заполняется байтами 0x00 до тех пор, пока не будет достигнут размер, кратный размеру блока.

С другой стороны, заполнение PKCS#5/PKCS#7 заполняет его байтами, которые обозначают количество байтов, отсутствующих до следующего кратного размера блока. Размер блока для DES составляет 8 байт.

Таким образом, вам либо нужно заполнить открытый текст в php (см. этот раскрывающийся код: A: Как добавить/удалить заполнение PKCS7 из AES зашифрованную строку?) или используйте другой шифр в ColdFusion, например "DES/ECB/NoPadding". Я рекомендую первое, потому что если вы используете NoPadding, открытый текст уже должен быть кратен размеру блока.

$key = "$224455@";
$Valor = "TESTE";
function pkcs7pad($plaintext, $blocksize)
{
    $padsize = $blocksize - (strlen($plaintext) % $blocksize);
    return $plaintext . str_repeat(chr($padsize), $padsize);
}

$base = chop(base64_encode(mcrypt_encrypt(MCRYPT_DES, $key, pkcs7pad($Valor, 8), MCRYPT_MODE_ECB)));

Результат:

qOQnhdxiIKs=

Не забудьте распаковать восстановленный открытый текст, если вы расшифровываете его в PHP.

person Artjom B.    schedule 07.03.2015
comment
Если не закодировать ключ с ошибкой Base64 Произошла ошибка при попытке зашифровать или расшифровать входную строку: '' Невозможно декодировать строку $224455@.. - person Hilso Vasques Junior; 07.03.2015
comment
Я нашел проблему. Заняло меня достаточно долго. - person Artjom B.; 07.03.2015
comment
(Изменить) @ArtjomB. - Как простая текстовая строка и ключ декодируются в php? CF всегда обрабатывает в кодировке UTF8 и ключ в формате base64. Таким образом, спрашивающему, вероятно, потребуется настроить ключ в зависимости от того, как функция php интерпретирует значение. - person Leigh; 07.03.2015
comment
@Leigh PHP использует двоичные строки. Таким образом, кодировка ввода зависит от кодировки файла php, которая, вероятно, является UTF-8. Выходные данные явно закодированы в Base64, чтобы соответствовать кодировке ColdFusion. Я вообще не знаю ColdFusion, чтобы сказать, почему ToBase64(Key) необходим и почему он выдает тот же результат, что и php-код в моем ответе. - person Artjom B.; 07.03.2015
comment
почему необходим ToBase64(Key) Я не очень хорошо знаком с php, но CF предполагает, что ключ уже закодирован в base64 (см. ссылку выше). Таким образом, он всегда декодирует ключевую строку как base64, чтобы получить ключевые байты. Предполагая, что это соответствует двоичному файлу, который получает php, возможно, поэтому он работает. (Изменить) Хорошая находка по поводу заполнения +1 - person Leigh; 07.03.2015
comment
@Ли Приятно знать. Я пытался найти подходящую документацию для шифрования ColdFusion через мою любимую поисковую систему во время поиска этого ответа, но с треском провалился. - person Artjom B.; 07.03.2015
comment
@ArtjomB. - Да, обычные документы по шифрованию не содержат достаточно подробной информации по IMO. внутренние работы. Другая ссылка выше гораздо полезнее, IMO, но мне потребовалось некоторое время, чтобы найти ее. - person Leigh; 07.03.2015
comment
Artjom, действительно работал над модификацией функции в PHP, но проблема в том, что я не могу ее модифицировать. Я не мог играть в CF. К сожалению, я могу только изменить CF - person Hilso Vasques Junior; 07.03.2015
comment
@HilsoVasquesJunior Я не могу вам с этим помочь, так как ничего не знаю о ColdFusion. - person Artjom B.; 07.03.2015
comment
@Leigh Может быть, вы можете дать ответ, где Valor заполнено 0x00 (\0) до следующего кратного 8, как это делает PHP. Если открытый текст уже кратен 8, его не следует изменять. - person Artjom B.; 07.03.2015
comment
@HilsoVasquesJunior. Проблема в том, что CF использует внутри себя основные библиотеки шифрования Java, и на основании того, что я прочитал 10309883#10309883">он может не поддерживать нулевое заполнение (игнорируйте часть AES). Вот почему обычно предлагается изменить файл PHP. - person Leigh; 07.03.2015
comment
Ли удалось сделать на PHP, а я попробую на CF. Если кто-то еще может мне помочь, спасибо, это не так просто. - person Hilso Vasques Junior; 08.03.2015
comment
Ребят, кажется нашел то что работает от CF. см. мой пост ниже. - person Leigh; 08.03.2015