sha1 函数给出与等效 .NET 代码不同的结果


sha1 function giving a different result to equivalent .net code

我有以下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写一个中间人并通过它进行中继,但我真的不想这样做。

对为什么两者给出不同的结果有什么见解吗?谢谢

这将做到这一点。 受到这篇文章和我 2 天前遇到的一个问题但找不到的启发。

public string HashItThePHPWay(string hashMe)
        {
            var sha = new SHA1CryptoServiceProvider();
            string b64 = ByteArrayToString(Encoding.ASCII.GetBytes(hashMe));
            var b64Bytes = Encoding.ASCII.GetBytes(b64);
            var result = sha.ComputeHash(b64Bytes);
            return BitConverter.ToString(result).Replace("-", "").ToLower();
        }
    public static string ByteArrayToString(byte[] ba)
    {
        StringBuilder hex = new StringBuilder(ba.Length * 2);
        foreach (byte b in ba)
        {
            hex.AppendFormat("{0:x2}", b);
        }
        return hex.ToString().ToLower();
    }