微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Java HMAC 在调用相同值时返回不同的 mac

如何解决Java HMAC 在调用相同值时返回不同的 mac

当尝试使用 HMAC 获取 mac 以验证请求的真实性时,我的函数总是返回不同的 mac,这意味着我无法使用该 mac 是不是我遗漏了什么?

private byte[] hmac(String algorithm,byte[] key,byte[] message) throws NoSuchAlgorithmException,InvalidKeyException {
        Mac mac = Mac.getInstance(algorithm);
        SecretKeySpec secretKeySpec = new SecretKeySpec(key,"AES");
        System.out.println("(client) AES "+secretKeySpec);
        mac.init(secretKeySpec);
        System.out.println("(client) MESSAGE "+message);
        mac.update(message);
        byte[]res=mac.doFinal();
        System.out.println("(client) MAC "+Base64.getEncoder().encode(res));
        return res;
    }

算法密钥和消息在我调用它们时总是相同的。算法为“HmacSHA256”

输出

(client) AES javax.crypto.spec.SecretKeySpec@fffe8334
(client) MESSAGE [B@15557ab5
(client) MAC [B@4ed3db30
(client) AES javax.crypto.spec.SecretKeySpec@fffe8334
(client) MESSAGE [B@15557ab5
(client) MAC [B@7563b5d

解决方法

您隐式使用了 Java toString() 数组的 byte[] 方法。

来自Oracle's Java 8 Base64.Encoder documentation for its encode() method

public byte[] encode(byte[] src)

将指定字节数组中的所有字节编码为新分配的 使用 Base64 编码方案的字节数组。返回的字节数组 是结果字节的长度。

参数:

src - 要编码的字节数组

退货:

一个新分配的字节数组,包含结果编码 字节。

注意返回类型是 byte[]

当你用一个字符串连接一个对象时,如

    System.out.println("(client) MAC "+Base64.getEncoder().encode(res));

您使用 toString() 方法将该对象转换为 Java String

根据 String Java documentation(我的粗体):

Java 语言为字符串连接运算符 ( + ) 以及将其他对象转换为字符串提供了特殊支持。字符串连接是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的。 字符串转换是通过方法toString实现的,由Object定义并被Java中的所有类继承。

Java 原始数组的 toString() 方法打印数组的类型,然后打印它的地址。

因此:

(client) MAC [B@7563b5d

[B 表示“byte[] 数组”,@7563b5d 可能是 byte[] Java Object 的地址(或其他一些 JVM 记帐标签) .

如果要打印 Java 原始数组(例如 byte[] 数组)的 CONTENTS,则需要使用 java.util.Arrays.toString() method .

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。