C# 中的 HMAC SHA256 哈希计算
HMAC SHA256 hash computation in C#
我需要使用 SHA256 哈希函数计算 HMAC。我有一个以 base64 格式编码的密钥。还有一个在线工具可以正确计算 HMAC(已验证)。
http://www.freeformatter.com/hmac-generator.html
我写了下面的代码片段:
var signatureHashHexExpected = "559bd871bfd21ab76ad44513ed5d65774f9954d3232ab68dab1806163f806447";
var signature = "123456:some-string:2016-04-12T12:44:16Z";
var key = "AgQGCAoMDhASFAIEBggKDA4QEhQCBAYICgwOEBIUAgQ=";
var shaKeyBytes = Convert.FromBase64String(key);
using (var shaAlgorithm = new System.Security.Cryptography.HMACSHA256(shaKeyBytes))
{
var signatureBytes = System.Text.Encoding.UTF8.GetBytes(signature);
var signatureHashBytes = shaAlgorithm.ComputeHash(signatureBytes);
var signatureHashHex = string.Concat(Array.ConvertAll(signatureHashBytes, b => b.ToString("X2"))).ToLower();
System.Diagnostics.Debug.Assert(signatureHashHex == signatureHashHexExpected);
}
问题:
我的代码没有生成正确的 HMAC。我通过使用不同的在线工具和替代 C# 实现验证了不同的步骤。只有从 base64 的转换未得到确认。我错过了什么?
更新:
我的代码计算出的 signatureHashHex 是 "a40e0477a02de1d134a5c55e4befa55d6fca8e29e0aa0a0d8acf7a4370208efc"
答案:
该问题是由误导性文档引起的,该文档指出密钥以 Base64 格式提供。查看已接受的答案:
var shaKeyBytes = System.Text.Encoding.UTF8.GetBytes(key);
您的结果是正确的,区别在于您link使用的工具不解码键值的Base64并将其视为一系列字符。
例如要复制其结果,请将您的密钥视为字符串:
var shaKeyBytes = System.Text.Encoding.UTF8.GetBytes("AgQGCAoMDhASFAIEBggKDA4QEhQCBAYICgwOEBIUAgQ=");
产生
559bd871bfd21ab76ad44513ed5d65774f9954d3232ab68dab1806163f806447
(这显然不是正确的做法)
HMAC: 消息认证 code.It 用于验证发送方的数据完整性,仅转发 algorithm.It 适用于共享发送方和接收方都知道的密钥 both.Before 生成哈希值,我们必须对密钥和消息进行编码。我们可以使用编码 UTF8 或 ASCIIEncoding.
中的一种
UTF8编码:
var signature = "123456:some-string:2016-04-12T12:44:16Z";
var key = "AgQGCAoMDhASFAIEBggKDA4QEhQCBAYICgwOEBIUAgQ=";
var signatureBytes = System.Text.Encoding.UTF8.GetBytes(signature);
var shaKeyBytes = System.Text.Encoding.UTF8.GetBytes(key);
ASCIIEncoding编码:
var signature = "123456:some-string:2016-04-12T12:44:16Z";
var key = "AgQGCAoMDhASFAIEBggKDA4QEhQCBAYICgwOEBIUAgQ=";
var signatureBytes = System.Text.ASCIIEncoding.GetBytes(signature);
var shaKeyBytes = System.Text.ASCIIEncoding.GetBytes(key);
现在我们可以在上面的代码中使用这个编码的消息和密钥了。
我需要使用 SHA256 哈希函数计算 HMAC。我有一个以 base64 格式编码的密钥。还有一个在线工具可以正确计算 HMAC(已验证)。 http://www.freeformatter.com/hmac-generator.html 我写了下面的代码片段:
var signatureHashHexExpected = "559bd871bfd21ab76ad44513ed5d65774f9954d3232ab68dab1806163f806447";
var signature = "123456:some-string:2016-04-12T12:44:16Z";
var key = "AgQGCAoMDhASFAIEBggKDA4QEhQCBAYICgwOEBIUAgQ=";
var shaKeyBytes = Convert.FromBase64String(key);
using (var shaAlgorithm = new System.Security.Cryptography.HMACSHA256(shaKeyBytes))
{
var signatureBytes = System.Text.Encoding.UTF8.GetBytes(signature);
var signatureHashBytes = shaAlgorithm.ComputeHash(signatureBytes);
var signatureHashHex = string.Concat(Array.ConvertAll(signatureHashBytes, b => b.ToString("X2"))).ToLower();
System.Diagnostics.Debug.Assert(signatureHashHex == signatureHashHexExpected);
}
问题: 我的代码没有生成正确的 HMAC。我通过使用不同的在线工具和替代 C# 实现验证了不同的步骤。只有从 base64 的转换未得到确认。我错过了什么?
更新: 我的代码计算出的 signatureHashHex 是 "a40e0477a02de1d134a5c55e4befa55d6fca8e29e0aa0a0d8acf7a4370208efc"
答案: 该问题是由误导性文档引起的,该文档指出密钥以 Base64 格式提供。查看已接受的答案:
var shaKeyBytes = System.Text.Encoding.UTF8.GetBytes(key);
您的结果是正确的,区别在于您link使用的工具不解码键值的Base64并将其视为一系列字符。
例如要复制其结果,请将您的密钥视为字符串:
var shaKeyBytes = System.Text.Encoding.UTF8.GetBytes("AgQGCAoMDhASFAIEBggKDA4QEhQCBAYICgwOEBIUAgQ=");
产生
559bd871bfd21ab76ad44513ed5d65774f9954d3232ab68dab1806163f806447
(这显然不是正确的做法)
HMAC: 消息认证 code.It 用于验证发送方的数据完整性,仅转发 algorithm.It 适用于共享发送方和接收方都知道的密钥 both.Before 生成哈希值,我们必须对密钥和消息进行编码。我们可以使用编码 UTF8 或 ASCIIEncoding.
中的一种UTF8编码:
var signature = "123456:some-string:2016-04-12T12:44:16Z";
var key = "AgQGCAoMDhASFAIEBggKDA4QEhQCBAYICgwOEBIUAgQ=";
var signatureBytes = System.Text.Encoding.UTF8.GetBytes(signature);
var shaKeyBytes = System.Text.Encoding.UTF8.GetBytes(key);
ASCIIEncoding编码:
var signature = "123456:some-string:2016-04-12T12:44:16Z";
var key = "AgQGCAoMDhASFAIEBggKDA4QEhQCBAYICgwOEBIUAgQ=";
var signatureBytes = System.Text.ASCIIEncoding.GetBytes(signature);
var shaKeyBytes = System.Text.ASCIIEncoding.GetBytes(key);
现在我们可以在上面的代码中使用这个编码的消息和密钥了。