1

我在 PHP 中有一个代码,当我执行下面的 PHP 代码时,当我运行 PHP 代码下面的 C# 代码时,我得到了不同的结果,我不知道我错在哪里。

$accessID = "member-1681fca809";
$secretKey = "63f22236ab43b69462b3272b110e3c78";

$expires = 1357039353;
$stringToSign = $accessID."\n".$expires;

$binarySignature = hash_hmac('sha1', $stringToSign, $secretKey, true);
$urlSafeSignature = urlencode(base64_encode($binarySignature));
print_r($expires);
print_r($urlSafeSignature);

I got Output
1357039353
M1PZW2DYVzdRV1l4ZHBPAmiv9iM%3D

当我在 c# 中运行相同的代码时,我得到了不同的输出

string accessid = "member-1681fca809";
string secretekey = "63f22236ab43b69462b3272b110e3c78";
int Expire = 1357039353;

string stringTosign = accessid + Environment.NewLine + Expire;
byte[] secret = UTF8Encoding.UTF8.GetBytes(secretekey);

HMACSHA1 myhmacsha1 = new HMACSHA1(secret);
byte[] byteArray = Encoding.ASCII.GetBytes(stringTosign);
MemoryStream stream = new MemoryStream(byteArray);
byte[] hashValue = myhmacsha1.ComputeHash(stream);
string k = Convert.ToBase64String(Encoding.ASCII.GetBytes(hashValue.ToString()));

console.WriteLine(Expire);
console.WriteLine(k);

I Got OutPut
1357039353
U3lzdGVtLkJ5dGVbXQ==
4

3 回答 3

2

稍微修改了你的代码。

string accessid = "member-1681fca809";
string secretekey = "63f22236ab43b69462b3272b110e3c78";
int Expire = 1357039353;

string stringTosign = accessid + "\n" + Expire;
byte[] secret = UTF8Encoding.UTF8.GetBytes(secretekey);

HMACSHA1 myhmacsha1 = new HMACSHA1(secret);
byte[] byteArray = Encoding.ASCII.GetBytes(stringTosign);
MemoryStream stream = new MemoryStream(byteArray);
byte[] hashValue = myhmacsha1.ComputeHash(stream);
string k = Convert.ToBase64String(hashValue);

Console.WriteLine(Expire);
Console.WriteLine(k);

唯一的区别是最后一个字符,因为您使用 url_encode 将转换“=”字符。

于 2013-01-01T12:16:50.317 回答
0

谢谢!问题解决了,还是想分享一下我的经验。

我犯的错误是我使用了字符串生成器 sbr.Append 而不是 sbr.AppendLine() 或直接字符串连接,就像你在 \n 被读取为新行时所做的那样。

于 2014-05-08T09:33:59.917 回答
0

当您获得 HMACSHA1/hash_hmac('sha1', ...) 的不同结果时,开始使用非常简单的输入(如 input = "a"、key = "b")对 PHP 和 C# 版本进行拆分测试。如果您在将密钥传递给 HMACSHA1 之前对其进行编码,请检查您的编码是否正确。我花了几个小时认为问题是 HMACSHA1 散列,而实际上它是一个糟糕的 pack('H*'...) 实现。

public static string Encode(string input, byte[] key)
{
    HMACSHA1 myhmacsha1 = new HMACSHA1(key);
    byte[] byteArray = Encoding.ASCII.GetBytes(input);
    MemoryStream stream = new MemoryStream(byteArray);
    return myhmacsha1.ComputeHash(stream).Aggregate("", (s, e) => s + String.Format("{0:x2}", e), s => s);
}

和 pack('H*'...) C# 实现:

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;
}

当您将内容传递给 Encode 函数时,请勿将内容从字节数组转换为字符串然后再转换回字节数组,只需传递一个 byte[] 并保持简单。

于 2015-09-15T21:42:47.293 回答