【发布时间】:2014-11-26 20:40:04
【问题描述】:
我有以下 PHP 代码:
$stringToHash = "10123456789"."2014:11:25-15:42:00"."20.00"."826"."sharedsecret";
echo($stringToHash);
// outputs:
// 101234567892014:11:25-15:42:0020.00826sharedsecret
$ascii = bin2hex($stringToHash);
echo($ascii);
// outputs:
// 3130313233343536373839323031343a31313a32352d31353a34323a303032302e3030383236736861726564736563726574
$sha = sha1($ascii);
echo($sha);
// outputs:
// 847aa9da32c54ed8bb9183007336f5762a62ef20
这是等效的 C# 代码:
var stringToHash = "10123456789" + "2014:11:25-15:42:00" + "20.00" + "826" + "sharedsecret";
Console.WriteLine(stringToHash);
// outputs:
// 101234567892014:11:25-15:42:0020.00826sharedsecret
var bytes = Encoding.ASCII.GetBytes(stringToHash);
var hexString = BitConverter.ToString(bytes).Replace("-", string.Empty);
Console.WriteLine(hexString);
// outputs:
// 3130313233343536373839323031343A31313A32352D31353A34323A303032302E3030383236736861726564736563726574
SHA1 sha = new SHA1CryptoServiceProvider();
var password = sha.ComputeHash(bytes);
var result = BitConverter.ToString(password).ToLower().Replace("-", string.Empty);
Console.WriteLine(result);
// outputs:
// c8069048623d6b98a08454e43e1a02a42cf7d61d
var hexStringBytes = Encoding.ASCII.GetBytes(hexString);
var hexStringPassword = sha.ComputeHash(hexStringBytes);
var hexStringResult = BitConverter.ToString(hexStringPassword).ToLower().Replace("-", string.Empty);
Console.WriteLine(hexStringResult);
// outputs:
// bd857ca08446001f7182fbbbd41e747abe302a87
前两个输出是相同的。原始字符串是相同的,转换后的 ASCII 十六进制数组也是相同的,但是 PHP 中的 sha1() 给了我与 .net 的 SHA1CryptoServiceProvider 不同的结果。如果我将该输出转换为字符串并再次对其进行哈希处理,结果也会有所不同。
在 .net 中,对象必须采用字节数组的形式,然后才能从中创建 SHA 哈希,我不明白我需要转换为字节数组以产生与PHP 代码。
这是有问题的,因为我发布到的第三方服务使用 PHP 版本来验证他们端的对象,并且我的程序是用 .net 编写的。我可以用 PHP 编写一个中间人并通过它进行中继,但我真的不想这样做。
任何关于为什么两者给出不同结果的见解?谢谢
【问题讨论】:
-
您忘记在 C# 程序中实际使用
hexString。我不明白你为什么要在散列之前使用十六进制字符串,但是你错过了 .net 中的那一步是问题所在。 -
hexstring肯定只是十六进制字节数组的字符串表示形式吗?我正在使用字节数组,我只是将其转换为字符串以将其打印到控制台并查看它是否与该阶段的 PHP 等效项匹配。你是说我应该取那个字符串,将它转换回一个字节数组并散列它以获得与 PHP 相同的结果吗?至于为什么,这是第三方提供的示例代码,展示了他们如何计算哈希值,我正在尝试在 C# 中复制它。 -
您正在转换 2 个不同的值。 PHP 转换十六进制,.net 不。
-
有什么区别呢?我以为它们只是表示相同数据(base8/base16)的两种方式?那么在 C# 中对字节数组进行哈希处理就相当于在 php 中对十六进制数组进行哈希处理?
-
以编程方式,这些值将是等效的。但不是在散列一些东西的计划中。散列“cat”的 ascii 值与散列二进制等效项不同。