我正在编写一个Drupal支付方法模块,在此我需要生成一个哈希发送给银行。 Bank要求我将某些字符串编码到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函数之后。
答案 0 :(得分:1)
简单的解决方案:
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。
答案 1 :(得分:0)
你的明文B7DC02D5D6F2689E
是8个字节= 64位。这是DES的精确块,因此您无需在ECB模式下进行任何填充。我建议你完全删除填充代码。在这种情况下,所有DEC-ECB需要的是加密块和密钥;没有填充,没有IV。