【问题标题】:Why do I get an different hash when running with python and C# the same key and message?为什么使用 python 和 C# 运行相同的密钥和消息时会得到不同的哈希?
【发布时间】:2020-07-08 14:38:00
【问题描述】:

这有点让我发疯。我在 C# 中有这段代码,我正在尝试将其转换为 python,但由于某种原因,我无法获得相同的哈希值。

using System.Text;
using System.Security.Cryptography;

public class Program
{
    public static void Main()
    {
        // input, plain text here
        string key = "8ea79bcec3d54597efe186780a835c075400623a11481d3d17dd92e905dbb615";
        string tokenHash = "st=1585258906~exp=1585261006~acl=*";
        string encoded;
        HMACSHA256 hmac = new HMACSHA256(ParseHexBinary(key));
        byte[] bytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(tokenHash.ToString()));
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.Length; i++)
        {
            sb.Append(bytes[i].ToString("x2"));
        }

        encoded = sb.ToString();
        Console.WriteLine(encoded);
    }
    private static int HexToBinFn(char c)
        {
            if ('0' <= c && c <= '9')
            {
                return c - '0';
            }
            char c2 = 'A';
            if ('A' > c || c > 'F')
            {
                c2 = 'a';
                if ('a' > c || c > 'f')
                {
                    return -1;
                }
            }
            return (c - c2) + 10;
        }

        public static byte[] ParseHexBinary(String str)
        {
            int length = str.Length;
            byte[] bytes = new byte[(length / 2)];

                for (int i = 0; i < length; i += 2)
                {
                    int bin1 = HexToBinFn(str[i]);
                    int bin2 = HexToBinFn(str[i + 1]);

                    int i2 = (bin1 * 16) + bin2;
                    byte b = (byte)i2;

                    bytes[i / 2] = b;
                }

            return bytes;
        }
}

使用 C# 我得到这个哈希:988b6a86f25529ad8a8c2da42bf95a0ca24ea113fb05fcb6e356096852693dda

这是我的python代码:

import hashlib
import hmac
import base64

key = '8ea79bcec3d54597efe186780a835c075400623a11481d3d17dd92e905dbb615'
tokenHash = 'st=1585258906~exp=1585261006~acl=*'
x = hmac.new(key.encode('utf-8'), tokenHash.encode('utf-8'), hashlib.sha256).hexdigest()

使用 python 我得到这个哈希:8cbb2096d5e201454bb6797b4689a524d2d7d1def51c4b66ec6b1e4a99a509cf

谁能告诉我区别在哪里?我不知道怎么翻译。非常感谢。

【问题讨论】:

  • 目前您对每种方法的效果如何?
  • 首先要检查的是,假设您请求相同类型的哈希,您是否在明文中包含尾随换行符。
  • 我没有添加任何尾随换行符。但我不确定问题是什么:(

标签: c# python encryption


【解决方案1】:

我不知道 python 对您作为 hmac.new 方法的密钥提供的 string 做了什么,但它似乎没有将十六进制转换为字节,这就是为什么您会得到不同的哈希值.如果我先在 python 中将十六进制转换为字节,那么它们都会产生相同的哈希。

import hashlib
import hmac
import base64
import binascii

key = '8ea79bcec3d54597efe186780a835c075400623a11481d3d17dd92e905dbb615'
keyBytes = binascii.unhexlify(key)
tokenHash = 'st=1585258906~exp=1585261006~acl=*'
x = hmac.new(keyBytes, tokenHash.encode('utf-8'), hashlib.sha256).hexdigest()

因此,它们似乎不会产生相同的哈希,因为密钥不同。

如果您无法修改 python 代码,那么在 C# 中,不要将 key 视为十六进制字符串并将其转换为 byte[],您只需获取字符串的 UTF8 字节,然后它们会生成相同的哈希。至少对我来说。

//var keyBytes = ParseHexBinary(key); Instead of this...
var keyBytes = Encoding.UTF8.GetBytes(key); //Do this.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    • 2017-09-02
    • 1970-01-01
    • 2015-07-11
    相关资源
    最近更新 更多