PHP 中的 DES 加密

发布于 2024-11-29 11:29:58 字数 1708 浏览 1 评论 0原文

我正在编写一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七秒鱼° 2024-12-06 11:29:58

简单的解决方案:

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 来进行这样的单块加密。

Simple solution:

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

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

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 no hex2bin() function, so you have to use pack() instead.)

You also don't need an IV for a single-block encryption like this.

一紙繁鸢 2024-12-06 11:29:58

明文 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文