PHP 中的 DES 加密
我正在编写一个 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 函数之后。
I am coding a Drupal payment method module and within this I need to generate a hash to send to a bank. Bank asks me to code certain strings into the DES/ECB hash. They also provide test environment and here comes my problem. With the string B7DC02D5D6F2689E and key 7465737465703031 I should get result hash 3627C7356B25922B (after bin2hex, of course). This is by the bank test page and I have also checked this on this page: http://www.riscure.com/tech-corner/online-crypto-tools/des.html (encryption java applet).
My problem is that whatever I do I cant get my PHP code to provide the correct result. This is a simple function I am trying to use:
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;
}
and I have been trying sth like this as well:
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;
}
None of these gave the correct signature. Any idea what's wrong? For now I am dealing with this issue more than 3 hrs, so I appreciate any help. I am not very familiar with this encryption stuff. Thanks a lot.
Btw.: Those $hash and $key mentioned above are after the strtoupper, substr and bin2hex functions at the beginning of my code snippets.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
简单的解决方案:
这会为我打印
3627c7356b25922b
,所以看起来这很有效。您使用
bin2hex()
的方法是正确的,但转换方向错误。 (不幸的是,没有hex2bin()
函数,因此您必须使用pack()
来代替。)您也不需要 IV 来进行这样的单块加密。
Simple solution:
This prints
3627c7356b25922b
for me, so it looks like that's working.You were on the right track with
bin2hex()
, but that was converting in the wrong direction. (There's unfortunately nohex2bin()
function, so you have to usepack()
instead.)You also don't need an IV for a single-block encryption like this.
明文
B7DC02D5D6F2689E
为 8 字节 = 64 位。这是 DES 的精确块,因此在 ECB 模式下不需要任何填充。我建议您完全删除填充代码。在这种情况下,DEC-ECB 所需要的只是要加密的块和密钥;没有填充,也没有 IV。You plaintext,
B7DC02D5D6F2689E
, is 8 bytes = 64 bits. This is an exact block for DES so you don't need any padding in ECB mode. I suggest that you remove the padding code entirely. All DEC-ECB needs in this case is the block to encrypt and the key; no padding and no IV.