简体   繁体   English

尝试在 C# 中复制哈希示例

[英]Trying to replicate a Hash example in C#

I'm trying to consume an API and for that purpose I have to create a signature using SHA384.我正在尝试使用 API,为此我必须使用 SHA384 创建签名。 The docs describe doing:文档描述了做:

signature = hex(HMAC_SHA384(base64(payload), key=api_secret))

They give an example:他们举了一个例子:

~$ base64 << EOF
> {
>     "request": "/v1/order/status",
>     "nonce": 123456,
>
>     "order_id": 18834
> }
> EOF
ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYs
CgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=
In this example, the api_secret is 1234abcd

echo -n 'ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYsCgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=' | openssl sha384 -hmac "1234abcd"
(stdin)= 337cc8b4ea692cfe65b4a85fcc9f042b2e3f702ac956fd098d600ab15705775017beae402be773ceee10719ff70d710f

It took a little while, but I realized that in order to replicate the base64 of the original string I had to replace "\\r\\n" with "\\n".花了一点时间,但我意识到为了复制原始字符串的 base64,我必须用“\\n”替换“\\r\\n”。

Here's what I've got (ignoring the formatting that I wasted 20 minutes trying to make good):这是我所得到的(忽略我浪费了 20 分钟试图做好的格式):

            var raw = @"{
""request"": ""/v1/order/status"",
""nonce"": 123456,

""order_id"": 18834

} ";

         var data = raw.Replace("\r\n", "\n");
        Console.WriteLine(data);
        var data64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(data.ToCharArray()));
        if (data64 != "ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYsCgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=")
        {
            Console.WriteLine("base64's don't match");
        }
        Console.WriteLine("ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYsCgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=");
        Console.WriteLine(data64);

        var key = Encoding.UTF8.GetBytes("1234abcd");
        using (var hash = new HMACSHA384(key))
        {
            var hash64 = Convert.ToBase64String(hash.ComputeHash(Encoding.UTF8.GetBytes(data64)));

            StringBuilder sb = new StringBuilder();
            foreach (char c in hash64)
            {
                sb.Append(Convert.ToInt32(c).ToString("x"));
            }

            Console.WriteLine(sb.ToString());
            // yields:
            // 4d337a49744f70704c50356c744b68667a4a38454b79342f6343724a5676304a6a57414b7356634664314158767135414b2b647a7a753451635a2f3344584550
            // should be:
            // 337cc8b4ea692cfe65b4a85fcc9f042b2e3f702ac956fd098d600ab15705775017beae402be773ceee10719ff70d710f
        }

My code's output doesn't match the documentation's expected output.我的代码输出与文档的预期输出不匹配。 Can someone see what I'm doing wrong?有人能看到我做错了什么吗?

For some reason you are converting hash to base-64 string, then you convert each character of that string to int and that you convert to hex.出于某种原因,您将哈希转换为 base-64 字符串,然后将该字符串的每个字符转换为 int 并转换为十六进制。 All that is not needed and not described in "documentation".所有不需要的和“文档”中没有描述的。 Instead, do like this:相反,请这样做:

var hashBin = hash.ComputeHash(Encoding.UTF8.GetBytes(data64));
var hashHex = BitConverter.ToString(hashBin).Replace("-", "").ToLowerInvariant();
Console.WriteLine(hashHex);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM