C# 相当于 PHP 中的 hash_hmac

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12804231/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 00:32:11  来源:igfitidea点击:

C# equivalent to hash_hmac in PHP

c#hmacsha512

提问by Philippe

using .NET and C# i need to provide an integrity string using HMAC SHA512 to a PHP server . Using in C# :

使用 .NET 和 C# 我需要使用 HMAC SHA512 向 PHP 服务器提供完整性字符串。在 C# 中使用:

Encoding encoding = Encoding.UTF8;
byte[] keyByte = encoding.GetBytes(key);
HMACSHA512 hmacsha512 = new HMACSHA512(keyByte);
byte[] messageBytes = encoding.GetBytes(message);
byte[]  hashmessage = hmacsha512.ComputeHash(messageBytes);
return(ByteToString(hashmessage).toUpper());

But it doesn't match with PHP hash_hmac() PHP code :

但它与 PHP hash_hmac() PHP 代码不匹配:

$hmac = strtoupper(hash_hmac($pbx_hash, $msg, $binKey));

I try to change encoding in C# (utf8, ASCII,Unicode) Without success.

我尝试在 C# (utf8, ASCII, Unicode) 中更改编码但没有成功。

I've tried many solution found on the net but nothing give the same string :(

我尝试了很多在网上找到的解决方案,但没有给出相同的字符串:(

I can't change the PHP code, and doesn't see what's wrong in C#

我无法更改 PHP 代码,也看不到 C# 中有什么问题

EditThis is ByteToString(copied from the comment):

编辑这是ByteToString(从评论中复制):

static string ByteToString(byte[] buff)
{
    string sbinary = "";
    for (int i = 0; i < buff.Length; i++)
    {
        sbinary += buff[i].ToString("X2"); /* hex format */
    }
    return (sbinary);
}    

After many tets, in found that i get the same results if PHP hash_hmac key is a string, not a byte Array . Seems that the problem is with the PHP convert function $binKey = pack("H*", $keyTest);

经过多次测试,发现如果 PHP hash_hmac 键是字符串,而不是字节数组,我会得到相同的结果。似乎问题出在 PHP 转换函数 $binKey = pack("H*", $keyTest);

回答by sehe

The problem must be the actual representation of the key/message data.

问题必须是密钥/消息数据的实际表示。

See the following tests:

请参阅以下测试:

PHP

PHP

#!/usr/bin/php
<?php
print strtoupper(hash_hmac("sha256", "message", "key"));
?>

Output (live via http://writecodeonline.com/php/):

输出(通过http://writecodeonline.com/php/直播):

6E9EF29B75FFFC5B7ABAE527D58FDADB2FE42E7219011976917343065F58ED4A

C#

C#

using System;
using System.Text;
using System.Security.Cryptography;

public class Program
{
    private const string key = "key";
    private const string message = "message";
    private static readonly Encoding encoding = Encoding.UTF8; 

    static void Main(string[] args)
    {
        var keyByte = encoding.GetBytes(key);
        using (var hmacsha256 = new HMACSHA256(keyByte))
        {
            hmacsha256.ComputeHash(encoding.GetBytes(message));

            Console.WriteLine("Result: {0}", ByteToString(hmacsha256.Hash));
        }
    }
    static string ByteToString(byte[] buff)
    {
        string sbinary = "";
        for (int i = 0; i < buff.Length; i++)
            sbinary += buff[i].ToString("X2"); /* hex format */
        return sbinary;
    }    
}

Output (live via http://ideone.com/JdpeL):

输出(通过http://ideone.com/JdpeL直播):

Result: 6E9EF29B75FFFC5B7ABAE527D58FDADB2FE42E7219011976917343065F58ED4A

So, check the character set/encoding of the PHP input data. Also check the actual algorithm (in $pbx_hash).

因此,请检查 PHP 输入数据的字符集/编码。还要检查实际算法(在 中$pbx_hash)。

回答by Philippe

As said upper, the problem was with PHP Pack(H* function used to convert key to byte array. C# Getbytes doesn't give the same result (utf8, asci, unicode...). The solution found here : http://www.nuronconsulting.com/c-pack-h.aspxwas ok for me. now HMAC from C# match with PHP !

如上所说,问题出在 PHP Pack(用于将键转换为字节数组的 H* 函数。C# Getbytes 没有给出相同的结果(utf8、asci、unicode...)。解决方案在这里找到:http:/ /www.nuronconsulting.com/c-pack-h.aspx对我来说没问题。现在来自 C# 的 HMAC 与 PHP 匹配!

public static byte[] PackH(string hex)
{
       if ((hex.Length % 2) == 1) hex += '0';
       byte[] bytes = new byte[hex.Length / 2];
       for (int i = 0; i < hex.Length; i += 2)
       {
             bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
       }
 return bytes;
}

Manu thanks to all for your help.

Manu 感谢大家的帮助。

回答by Micah Osborne

    private static string HashHmac(string message, string secret)
    {
        Encoding encoding = Encoding.UTF8;
        using (HMACSHA512 hmac = new HMACSHA512(encoding.GetBytes(secret)))
        {
            var msg = encoding.GetBytes(message);
            var hash = hmac.ComputeHash(msg);
            return BitConverter.ToString(hash).ToLower().Replace("-", string.Empty);
        }
    }