2

我正在编写一个 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 函数之后。

4

2 回答 2

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。

于 2011-08-16T00:35:13.400 回答
0

您的明文 ,B7DC02D5D6F2689E是 8 字节 = 64 位。这是 DES 的精确块,因此您在 ECB 模式下不需要任何填充。我建议您完全删除填充代码。在这种情况下,DEC-ECB 需要的只是要加密的块和密钥;没有填充,也没有 IV。

于 2011-08-16T00:33:26.253 回答