Подтвердить что ты не робот

Выяснение точного ключа, созданного PHP mcrypt

Приложение PHP, которое я поддерживаю, использует Rijndael_256 с шифрованием EBC_MODE с помощью mcrypt. У Fun есть то, что ключ не 256 бит в длину, а только 160. Согласно документации mcrypt_encrypt ключ дополняется \0 для получения требуемого размера, если он слишком мал.

Ключ, с которым данные будут зашифрованы. Если он меньше, чем требуемый ключ, он дополняется "\ 0". Лучше не использовать Строки ASCII для ключей.

Это похоже на начало строки 1186 в mcrypt.c и изменение ключа в строке 1213.

Так что скажем, у нас есть $key = 'abcdefghijkm';, который слишком короткий, но PHP-реализация mcrypt обеспечивает его расширение до 32 символов (или 256 бит) при использовании RIJNDAEL_256. Как будет выглядеть последний ключ?

Я прошу об этом, потому что создается другое приложение, которое использует одни и те же зашифрованные данные, но находится на другом языке. Perl, если быть точным, и я использую Crypto::Rijndael. Для данного примера ключа, каков точный ключ, который я должен был бы передать на Crypto::Rijndael (или любой другой, если на то пошло), чтобы снова расшифровать данные?

Обновление

С Perl я могу сгенерировать ключ, который \0 заполняется do pack('a32', 'my secret key'); (или Z32), length() будет сообщать 32, а модуль Crypt::Rijndael принимает ключ. Глядя на источник PHP mcrypt, это должен быть ключ, который генерируется (\ 0 padded), но он просто не принимает его.

Теоретически в PHP pack('a32', 'my secret key'); должен появиться тот же \0 -проложенный ключ, который генерирует PHP mcrypt, но это не так.

Я очень близок к простому шифрованию всего, но с новым ключом. Это занимает слишком много времени.

4b9b3361

Ответ 1

Проблема не в заполнении клавиш, а в том, что вы используете два разных размера блока. В PHP использование MCRYPT_RIJNDAEL_256 использует размер блока... 256 бит. Однако в perl с использованием Crypt::Rijndael они отмечают:

размер_блока
Блокировка для Rijndael составляет 16 байт (128 бит), хотя алгоритм фактически поддерживает любой размер блока, который является любым кратным нашим байтам. 128 бит, однако, размер блока, указанный AES, так что это все, что мы поддерживаем.

Таким образом, нет ключа, который позволит конвертировать между этими разными алгоритмами. Вы можете переключиться на 128 бит в PHP:

<?
$key = "abcdefghijklmnopqrstuvwxyz";
$data = "Meet me at 11 o'clock behind the monument.";
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB, nil);
echo bin2hex($crypttext) . "\n";
// prints c613d1804f52f535cb4740242270b1bcbf85151ce4c874848fd1fc2add06e0cc2d26b6403feef4a8df18f7dd7f8ac67d
?>

Какой Perl может расшифровать без проблем с помощью Crypt:: Rijndael:

use Crypt::Rijndael;
$key = "abcdefghijklmnopqrstuvwxyz\0\0\0\0\0\0";
$crypttext = "c613d1804f52f535cb4740242270b1bcbf85151ce4c874848fd1fc2add06e0cc2d26b6403feef4a8df18f7dd7f8ac67d";
$cipher = Crypt::Rijndael->new($key, Crypt::Rijndael::MODE_ECB());
print $cipher->decrypt(pack('H*', $crypttext));
# prints "Meet me at 11 o'clock behind the monument."

Или вы можете переключиться на другой модуль Perl, который поддерживает больше размеров блоков, например Crypt:: Rijndael_PP:

# Same PHP code except using MCRYPT_RIJNDAEL_256
# prints f38469ec9deaadbbf49bb25fd7fc8b76462ebfbcf149a667306c8d1c033232322ee5b83fa87d49e4e927437647dbf7193e6d734242d583157b492347a2b1514c

Perl:

use Crypt::Rijndael_PP ':all';
$key = "abcdefghijklmnopqrstuvwxyz\0\0\0\0\0\0";
$crypttext = "f38469ec9deaadbbf49bb25fd7fc8b76462ebfbcf149a667306c8d1c033232322ee5b83fa87d49e4e927437647dbf7193e6d734242d583157b492347a2b1514c";
print rijndael_decrypt(unpack('H*', $key), MODE_ECB, pack('H*', $crypttext), 256, 256);
# prints "Meet me at 11 o'clock behind the monument."

Ответ 2

'\ 0' означает NULL, его шестнадцатеричное значение равно 00! Поэтому я протестировал 3 кода, и они все равно вернулись:)

  • Пусть mcrypt_encrypt выполняет дополнение "\ 0"
  • Добавлены значения PHP NULL
  • Добавлено с PHP преобразованными 0 шестнадцатеричными значениями

код:   

function encryptThis($text,$key){
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
    return ($crypttext);
}

echo bin2hex(encryptThis("Meet me at 11 o'clock behind the monument.", "abcdefghijklmnopqrstuvwxyz"))."<br/>";

echo bin2hex(encryptThis("Meet me at 11 o'clock behind the monument.", "abcdefghijklmnopqrstuvwxyz" . NULL . NULL . NULL . NULL . NULL . NULL))."<br/>";

echo bin2hex(encryptThis("Meet me at 11 o'clock behind the monument.", "abcdefghijklmnopqrstuvwxyz" . hex2bin(0) . hex2bin(0) . hex2bin(0) . hex2bin(0) . hex2bin(0) . hex2bin(0)))."<br/>";

?>