VB.net和PHP之间的MD5哈希
在@JonSkeet的帮助下回答 鉴于此代码:VB.net和PHP之间的MD5哈希,php,.net,md5,Php,.net,Md5,在@JonSkeet的帮助下回答 鉴于此代码: Dim data1ToHash As Byte() = (New UnicodeEncoding).GetBytes(input) ' 2. Hash the byte array Dim hashvalue1 As Byte() = CType(CryptoConfig.CreateFromName("MD5"), HashAlgorithm).ComputeHash(data1ToHash) 这个PHP不应该生成正确的
Dim data1ToHash As Byte() = (New UnicodeEncoding).GetBytes(input)
' 2. Hash the byte array
Dim hashvalue1 As Byte() = CType(CryptoConfig.CreateFromName("MD5"), HashAlgorithm).ComputeHash(data1ToHash)
这个PHP不应该生成正确的散列吗
$md5=(md5(utf8_编码($signature),true))代码>
我试过了,但是MD5的总数不匹配。我假设这是编码,但可能与字节数组有关,有人能解释一下吗?仅供参考,我无法更改VB
要比较结果,请执行以下操作:
在.Net中
For Each b As Byte In hashvalue1
tb.Text = tb.Text & b.ToString() & ","
Next
tb.Text = tb.Text.Trim(",")
在PHP中
打印(开箱('C*',包装('H*',md5($signature))
根据另一个问题不清楚您是如何比较结果的,但编码*肯定是个问题-您在VB代码中使用UTF-16,在PHP中使用UTF-8。您可以这样更改VB代码:
Dim data1ToHash As Byte() = Encoding.UTF8.GetBytes(input)
MD5部件也可以简化,从而得到以下结果:
Dim unhashed As Byte() = Encoding.UTF8.GetBytes(input)
Dim hashed As Byte() = MD5.Create().ComputeHash(unhashed)
编辑:如果不能更改VB,则需要将PHP更改为使用UTF-16,如注释中所建议的那样。当然,您需要知道现有的编码是什么…不清楚您是如何比较结果的,但是编码*肯定是个问题-您在VB代码中使用UTF-16,在PHP中使用UTF-8。您可以这样更改VB代码:
Dim data1ToHash As Byte() = Encoding.UTF8.GetBytes(input)
MD5部件也可以简化,从而得到以下结果:
Dim unhashed As Byte() = Encoding.UTF8.GetBytes(input)
Dim hashed As Byte() = MD5.Create().ComputeHash(unhashed)
编辑:如果不能更改VB,则需要将PHP更改为使用UTF-16,如注释中所建议的那样。当然,您需要知道现有的编码是什么…解决方案与字节排序有关:.NET在UTF-16中是小端,而PHP的默认UTF-16编码是大端。所以答案是:
mb_internal_encoding('UTF-8');
$string = mb_convert_encoding($signature, 'UTF-16LE', 'UTF-8');
$encoded_signature = base64_encode(md5($string, true));
为了验证,我比较了PHP和.NET中的UTF-16编码字节:
print_r(unpack('C*', $string));
就这么简单。感谢大家的帮助,特别是@JonSkeet。解决方案与字节排序有关。UTF-16中的NET是Little-Endian,而PHP默认的UTF-16编码是Big-Endian。所以答案是:
mb_internal_encoding('UTF-8');
$string = mb_convert_encoding($signature, 'UTF-16LE', 'UTF-8');
$encoded_signature = base64_encode(md5($string, true));
为了验证,我比较了PHP和.NET中的UTF-16编码字节:
print_r(unpack('C*', $string));
就这么简单。感谢所有帮助过你的人,特别是@JonSkeet。确认你正在散列的数据是相同的。可能重复的确认你正在散列的数据是相同的。可能重复的好点,我会更新帖子,但我恐怕无法更改VB。@scottkf您可能可以使用PHP从UTF8转换为UTF16。@jon skeet那么下面的结果不应该正确吗<代码>$string=mb_转换_编码(utf8_编码($signature),'UTF-8','UTF-16')代码>$md5=(md5($string,true))
@scottkf:No,因为在将UTF-16版本传递给md5之前,您仍然将其编码为UTF-8(实际上,这种编码方式是错误的,因为utf8_encode的输入需要iso-8859-1)。如果没有最终的utf8_编码,这可能没问题。但是我对PHP的字符串表示法知之甚少,无法确定。@JonSkeet:问题在于字节的表示法。VB.net使用LE表示UTF-16,而PHP的UTF-16实际上是big-endian。解决方案是:$string=mb_convert_编码($signature,'UTF-16LE','UTF-8')$encoded_signature=base64_encode(md5($string,true))代码>通过执行以下操作验证:$raw=unpack('C*',$string);打印(原始)代码>说得好,我会更新帖子,但恐怕我无法更改VB。@scottkf您可能可以使用PHP从UTF8转换为UTF16。@jon skeet那么下面的结果不应该正确吗<代码>$string=mb_转换_编码(utf8_编码($signature),'UTF-8','UTF-16')代码>$md5=(md5($string,true))
@scottkf:No,因为在将UTF-16版本传递给md5之前,您仍然将其编码为UTF-8(实际上,这种编码方式是错误的,因为utf8_encode的输入需要iso-8859-1)。如果没有最终的utf8_编码,这可能没问题。但是我对PHP的字符串表示法知之甚少,无法确定。@JonSkeet:问题在于字节的表示法。VB.net使用LE表示UTF-16,而PHP的UTF-16实际上是big-endian。解决方案是:$string=mb_convert_编码($signature,'UTF-16LE','UTF-8')$encoded_signature=base64_encode(md5($string,true))代码>通过执行以下操作验证:$raw=unpack('C*',$string);打印(原始)代码>