简体   繁体   English

MD5在VB.net和PHP之间进行哈希处理

[英]MD5 Hashing between VB.net and PHP

Answered with the help of @JonSkeet 在@JonSkeet的帮助下回答

Given this code: 鉴于此代码:

    Dim data1ToHash As Byte() = (New UnicodeEncoding).GetBytes(input)
    ' 2. Hash the byte array
    Dim hashvalue1 As Byte() = CType(CryptoConfig.CreateFromName("MD5"), HashAlgorithm).ComputeHash(data1ToHash)

Shouldn't this PHP produce the correct hash? 这个PHP不应该产生正确的哈希吗?

$md5 = (md5(utf8_encode($signature), true));

I tried, but the md5sums aren't matching up. 我试过了,但是md5sums没有匹配。 I assumed it was encoding, but perhaps it has to do with the byte array, can anyone shed some light on this? 我以为它是编码,但也许它与字节数组有关,任何人都可以对此有所了解吗? FYI I can't change the VB 仅供参考我不能改变VB

To compare the results: 要比较结果:

in .Net 在.Net

For Each b As Byte In hashvalue1
  tb.Text = tb.Text & b.ToString() & ","
Next
tb.Text = tb.Text.Trim(",")

in PHP 用PHP

print_r(unpack('C*', pack('H*', md5($signature))))

as per another question 按照另一个问题

It's not clear how you're comparing the results, but the encoding is *definitely a problem - you're using UTF-16 in the VB code, and UTF-8 in the PHP. 目前还不清楚你是如何比较结果的,但编码肯定是个问题 - 你在VB代码中使用UTF-16,在PHP中使用UTF-8。 You can change the VB code like this: 您可以像这样更改VB代码:

Dim data1ToHash As Byte() = Encoding.UTF8.GetBytes(input)

The MD5 part can also be simplified, giving this result: MD5部分也可以简化,结果如下:

Dim unhashed As Byte() = Encoding.UTF8.GetBytes(input)
Dim hashed As Byte() = MD5.Create().ComputeHash(unhashed)

EDIT: If you can't change the VB, you need to change the PHP to use UTF-16, potentially with mbstring as suggested in comments. 编辑:如果你不能改变VB,你需要改变PHP使用UTF-16,可能与评论中建议的mbstring一样。 You'll need to know what the existing encoding is, of course... 你需要知道现有的编码是什么,当然......

The solution had to do with byte ordering: .NET in UTF-16 was Little Endian, whereas PHP's default UTF-16 encoding is Big Endian. 解决方案与字节排序有关:UTF-16中的.NET是Little Endian,而PHP的默认UTF-16编码是Big Endian。 So the answer is: 所以答案是:

mb_internal_encoding('UTF-8');
$string = mb_convert_encoding($signature, 'UTF-16LE', 'UTF-8');
$encoded_signature = base64_encode(md5($string, true));

To verify, I compared the UTF-16 encoded bytes in PHP and .NET: 为了验证,我比较了PHP和.NET中的UTF-16编码字节:

print_r(unpack('C*', $string));

Just that simple. 就这么简单。 Thanks to everyone who helped, especially @JonSkeet. 感谢所有帮助过的人,特别是@JonSkeet。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM