如何在C#中生成HMAC签名

6

我正在尝试与一个需要加密请求体和某些变量并使用HMAC签名进行授权的第三方API集成。他们提供了一个示例JavaScript代码:

function generateHMACSignature(partnerID, partnerSecret,
httpMethod, requestURL, contentType, requestBody, timestamp) {
var requestPath = getPath(requestURL);
var queryString = getQueryString(requestURL);
if (httpMethod == 'GET' || !requestBody) {
requestBody = '';
}
var hashedPayload =
CryptoJS.enc.Base64.stringify(CryptoJS.SHA256(requestBody));
var requestData = [[httpMethod, contentType, timestamp,
requestPath, hashedPayload].join('\n'), '\n'].join('');
var hmacDigest =
CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(requestData,
partnerSecret));
return hmacDigest;
}

function getPath(url) {
var pathRegex = /.+?\:\/\/.+?(\/.+?)(?:#|\?|$)/;
var result = url.match(pathRegex);
if(!result){
pathRegex = /\/.*/;
result = url.match(pathRegex);
return result && result.length == 1 ? result[0] : '';
}
return result && result.length > 1 ? result[1] : '';
}

function getQueryString(url) {
var arrSplit = url.split('?');
return arrSplit.length > 1 ? url.substring(url.indexOf('?')+1) : '';
}

在网上搜索了关于C#如何进行SHA256和HMAC签名的代码:

 public static String GetHMAC(String text, String key)
        {
            var enc = Encoding.Default;
            HMACSHA256 hmac = new HMACSHA256(enc.GetBytes(key));
            hmac.Initialize();

            byte[] buffer = enc.GetBytes(text);
            return BitConverter.ToString(hmac.ComputeHash(buffer)).Replace("-", "").ToLower();
        }


        static string ComputeSha256Hash(string rawData)
        {
            // Create a SHA256   
            using (SHA256 sha256Hash = SHA256.Create())
            {
                // ComputeHash - returns byte array  
                byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData));

                // Convert byte array to a string   
                StringBuilder builder = new StringBuilder();
                for (int i = 0; i < bytes.Length; i++)
                {
                    builder.Append(bytes[i].ToString("x2"));
                }
                return builder.ToString();
            }
        }

        public static string Base64Encode(string plainText)
        {
            var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
            return System.Convert.ToBase64String(plainTextBytes);
        }

他提供的代码结果与转换后的代码不同,我的代码有问题吗?
简而言之,如何在C#中正确地使用CryptoJS.SHA256(); 和CryptoJS.HmacSHA256();?

你可能想要使用Encoding.UTF8而不是默认值来匹配JavaScript。 - bartonjs
也许您可以展示C#和Javascript的测试输入以及相应的输出结果? - ProgrammingLlama
1个回答

13

针对SHA256和HMAC部分,您可以这样做:

private string GetHMAC(string text, string key)
{
    key = key ?? "";

    using (var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(key)))
    {
        var hash = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(text));
        return Convert.ToBase64String(hash);
    }

}

谢谢,这是正确的!我得到了错误的HMAC,因为我尝试加密的消息中有一个空格。 - Win

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接