【问题标题】:Convert C# HMAC SHA256 to PHP将 C# HMAC SHA256 转换为 PHP
【发布时间】:2016-07-02 00:41:41
【问题描述】:

我有一个必须转换为 PHP 的 C# 方法。我尝试了几件事,但我仍然得到不同的结果。不幸的是,我无法更改 C# 应用程序上的任何内容。它必须保持原样。也许你们中的一个可以帮忙?

C#:

static public void Main ()
{
    string StringToSign = "test";
    string Key = "123456";

    //Calculate Signature
    string Signature = CalculateSignature(StringToSign, Key);

    Console.WriteLine ("StringToSign: " + StringToSign);
    Console.WriteLine ("Key: " + Key);
    Console.WriteLine ("Signature Caculated: " + Signature + "\r\n");
}

static private string CalculateSignature(String StringToSign, String Key)
{
    Encoding enc = Encoding.GetEncoding(65001);

    byte[] KeyHex = StringHexValuesToByteArray(Key);
    byte[] StringToSign_byte = enc.GetBytes(StringToSign);

    //Check Signature
    HMACSHA256 hmac = new HMACSHA256(KeyHex);
    byte[] hashValue = hmac.ComputeHash(StringToSign_byte);

    return BitConverter.ToString(hashValue).Replace("-", "");
}

static public byte[] StringHexValuesToByteArray(string str)
{
    if (str.Length % 2 != 0)
        return null;

    string s = string.Empty;
    byte[] ret = new byte[str.Length / 2];

    for (int run = 0; run < str.Length / 2; run++)
    {
        s = str.Substring(run * 2, 2);
        ret[run] = Convert.ToByte(s, 16);
    }
    return ret;
}

PHP:

public function send() {

    $stringToSign = 'test';
    $key = '123456';

    //Calculate Signature
    $signature = $this->calculateSignature($stringToSign, $key);

    print_r("StringToSign: " . $stringToSign . PHP_EOL);
    print_r("Key: " . $key . PHP_EOL);
    print_r("Signature Caculated: " . $signature . PHP_EOL);
}

private function calculateSignature($stringToSign, $key) {

    // check signature
    $hash = strtoupper(hash_hmac('sha256', $stringToSign, $key, false));
    return $hash;
}

为了更好的理解,下面是上面代码块的输出:

C#

StringToSign:测试

密钥:123456

签名计算: DA3617974490FB780F04F06287BF93B0F24A7F15970471146428B943FFDC7850

PHP

StringToSign:测试

组密钥:123456

签名计算:9D2BB116E1DF997FFE8A5139FC1D187F976C19579A138414A112BC2E39020EBA

【问题讨论】:

    标签: c# php sha256 hmac


    【解决方案1】:

    如果要修改 PHP 使其等同于 C#

    改变

    $hash = strtoupper(hash_hmac('sha256', $stringToSign, $key, false));
    

    到

    $hash = strtoupper(hash_hmac('sha256', $stringToSign, hex2bin($key), false));
    

    请务必检查代码是否适用于非 ASCII 字符,例如 àèéìòù。

    ideone here.

    如果要修改 C# 代码使其与 PHP 等价

    你把一切都复杂化了:

    static private string CalculateSignature(String stringToSign, String key)
    {
        byte[] key_byte = Encoding.UTF8.GetBytes(key);
        byte[] stringToSign_byte = Encoding.UTF8.GetBytes(stringToSign);
    
        //Check Signature
        HMACSHA256 hmac = new HMACSHA256(key_byte);
        byte[] hashValue = hmac.ComputeHash(stringToSign_byte);
    
        return BitConverter.ToString(hashValue).Replace("-", "");
    }
    

    没有任何十六进制。而不是使用Encoding.GetEncoding(65001),通常最好使用Encoding.UTF8,因为它对每个人都更清楚。

    请注意,编码可能存在问题。尝试计算 àèéìòù 之类的 hmac 以查看 PHP 使用的是哪种编码。

    【讨论】:

    • 不幸的是,我无法更改 C# 应用程序上的任何内容。它必须保持原样。实际上,密钥看起来像“8A46AA67F474FB3285D3A55F4798EB24BCFF460AF1529F07AD140DB77F579D3CD1A614C8D80A56952F2CB96ED60F8BDE0BCC398C196507008C404BD2DCDFF9D1”。我只是出于测试目的对其进行了更改。
    • @ChristianDornbusch 更新了回复。
    猜你喜欢
    • 1970-01-01
    • 2015-11-13
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    相关资源
    最近更新 更多