Шифрование DES в PHP

Я кодирую модуль способа оплаты Drupal, и в нем мне нужно сгенерировать хэш для отправки в банк. Банк просит меня закодировать определенные строки в хэш DES/ECB. Они также предоставляют тестовую среду, и здесь возникает моя проблема. Со строкой B7DC02D5D6F2689E и ключом 7465737465703031 я должен получить хэш результата 3627C7356B25922B (конечно, после bin2hex). Это тестовая страница банка, и я также проверил это на этой странице: http://www.riscure.com/tech-corner/online-crypto-tools/des.html (java-апплет для шифрования).

Моя проблема в том, что что бы я ни делал, я не могу заставить свой PHP-код предоставить правильный результат. Это простая функция, которую я пытаюсь использовать:

function encrypt($hash, $key)
{
$hash = strtoupper(substr(sha1($hash), 0, 16));
$key = strtoupper(bin2hex($key));

$block = mcrypt_get_block_size('des', 'ecb');
if (($pad = $block - (strlen($hash) % $block)) < $block) {
  $hash .= str_repeat(chr($pad), $pad);
}

$sig = strtoupper(bin2hex(mcrypt_encrypt(MCRYPT_DES, $key, $hash, MCRYPT_MODE_ECB)));
return $sig;
}

и я тоже пробовал что-то вроде этого:

function encrypt( $value, $key) {
$hash = strtoupper(substr(sha1($value), 0, 16));
$key = strtoupper(substr(bin2hex($key), 0, 16));
// encrypt hash with key
if (function_exists('mcrypt_module_open')) {         // We have mcrypt 2.4.x
  $td = mcrypt_module_open(MCRYPT_DES, "", MCRYPT_MODE_ECB, "");
  $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
  mcrypt_generic_init($td, $key, $iv);
  $signature = strtoupper(bin2hex(mcrypt_generic ($td, $hash)));
  mcrypt_generic_end ($td);
}
else
{                        // We have 2.2.x only
$signature = strtoupper(bin2hex(mcrypt_ecb (MCRYPT_3DES, $key, $hash, MCRYPT_ENCRYPT)));
}
return $signature;
}

Ни один из них не дал правильной подписи. Есть идеи, что случилось? На данный момент я занимаюсь этой проблемой более 3 часов, поэтому я ценю любую помощь. Я не очень хорошо разбираюсь в этом шифровании. Большое спасибо.

Кстати: упомянутые выше $hash и $key находятся после функций strtoupper, substr и bin2hex в начале моих фрагментов кода.


person petiar    schedule 15.08.2011    source источник
comment
В качестве побочного эффекта, если это для банка, я настоятельно рекомендую TRIPLEDES вместо DES... Хорошо известно, что DES не работает.   -  person Jeremy Holovacs    schedule 16.08.2011
comment
Не решение ОП.   -  person    schedule 16.08.2011


Ответы (2)


Простое решение:

function encrypt($hash, $key) {
    return mcrypt_encrypt("des", pack("H*", $key), pack("H*", $hash), "ecb");
}

print bin2hex(encrypt("B7DC02D5D6F2689E", "7465737465703031"));

Это печатает 3627c7356b25922b для меня, так что похоже, что это работает.

Вы были на правильном пути с bin2hex(), но это было неправильное направление. (К сожалению, функции hex2bin() нет, поэтому вместо нее нужно использовать pack().)

Вам также не нужен IV для такого одноблочного шифрования.

person Community    schedule 16.08.2011

Ваш открытый текст, B7DC02D5D6F2689E, составляет 8 байтов = 64 бита. Это точный блок для DES, поэтому в режиме ECB вам не нужно никаких дополнений. Я предлагаю вам полностью удалить код заполнения. Все, что нужно DEC-ECB в этом случае, — это блок для шифрования и ключ; без заполнения и без IV.

person rossum    schedule 16.08.2011