首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >不同编程语言中关于Hmac SHA256的问题

不同编程语言中关于Hmac SHA256的问题
EN

Stack Overflow用户
提问于 2019-03-06 15:38:06
回答 1查看 635关注 0票数 0

我在尝试将HMACSHA256 (散列)集成到不同的编程语言中时遇到了一个问题。我试图用Java和C#中的标准预定义方法来实现标准算法,并且在不同的语言中得到了不同的结果。下面是我的Java和C#实现:

Java:

代码语言:javascript
运行
复制
    public static String convertSHAWithSalt(String value, String salt)
                throws NoSuchAlgorithmException, InvalidKeyException {
            String data = "";
            try {
                MessageDigest md = MessageDigest.getInstance("SHA-256");
                md.update(salt.getBytes(StandardCharsets.UTF_8));
                byte[] bytes = md.digest(value.getBytes(StandardCharsets.UTF_8));
                StringBuilder sb = new StringBuilder();
                for (byte b : bytes) {
                    sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
                }
                data = sb.toString();
                System.out.println(data);
                } catch (NoSuchAlgorithmException e) {
                  e.printStackTrace();
               }
            }

字符串值'abcd‘和空盐值的结果:88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589

C#:

代码语言:javascript
运行
复制
       public static string createHash(string message, string secret)
        {

            byte[] keyByte = System.Text.Encoding.UTF8.GetBytes(secret);

            byte[] messageBytes = System.Text.Encoding.UTF8.GetBytes(message);

            HMACSHA256  hmacsha256 = new HMACSHA256(keyByte);
            byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
            return BitConverter.ToString(hashmessage).Replace("-", "").ToLower();
        }

字符串值'abcd‘和空盐值的结果:527ff4c28c22a090fe39908139363e81b8fb10d0695a135518006abfa21cf5a2

请说明为什么这两个结果会有差异。我也用java尝试了下面的实现,但它不能处理空的salt值:

代码语言:javascript
运行
复制
public static String convertSHAWithSalt(String value, String salt)
            throws NoSuchAlgorithmException, InvalidKeyException {
        String data = "";
        Mac sha256Hmac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretkey = new SecretKeySpec(salt.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            sha256Hmac.init(secretkey);
            data = bytesToHex(sha256Hmac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
            System.out.println(data);
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-06 20:59:23

SHA-256HMAC-SHA-256之间有一个differenceHMAC-SHA-256 (另请参阅HMAC)是使用SHA-256散列算法生成MAC散列的算法。

第一个Java代码和C#代码的结果是不同的,因为Java代码使用SHA-256和C#代码HMAC-SHA-256

由于您希望使用HMAC-SHA-256,因此我将重点放在这一点上,而忽略第一个Java代码。

文本的C#代码的结果

代码语言:javascript
运行
复制
This is an arbitrary text!

带着钥匙

代码语言:javascript
运行
复制
1234567890

代码语言:javascript
运行
复制
25583e6e0b6c2c3a5c50ebd9ea48138a960a7ca2a215fae2b4b82ee99734deb4

第二个Java代码也使用HMAC-SHA-256。如果您替换这些行

代码语言:javascript
运行
复制
data = bytesToHex(sha256Hmac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
System.out.println(data);

使用

代码语言:javascript
运行
复制
data = bytesToHex(sha256Hmac.doFinal(value.getBytes(StandardCharsets.UTF_8)));
return data;

然后,输出是相同的(如果你的(未发布的) bytesToHex-method以适当的方式工作,请参见例如How to convert a byte array to a hex string in Java?)。

顺便说一句,在第二个Java代码中,您应该将标签salt更改为类似于key的内容,因为这是MAC上下文中的常见措辞。salt通常与密码散列结合使用,就像您的第一个Java代码中那样。

注意:在Java代码中,不允许使用空字节数组作为SecretKeySpec-input。这将抛出一个IllegalArgumentException (Empty key)。但是,C#代码中的HMACSHA256-ctor接受一个空字节数组,并在内部用0值填充它。因此,对于您的测试用例(text:abcd,空键),您可以在Java代码中通过一个包含单个0值的字节数组来模拟空字节数组。然后,Java代码的输出等于C#代码的输出。当然,空键应该只用于这个测试用例。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55017871

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档