Java HMAC returns 不同 mac 当调用相同的值时

Java HMAC returns different mac when called on same value

当尝试使用 HMAC 获取 mac 来验证请求的真实性时,我的函数总是 returns 不同的 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 byte[] 数组的 toString() 方法。

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

public byte[] encode(byte[] src)

Encodes all bytes from the specified byte array into a newly-allocated byte array using the Base64 encoding scheme. The returned byte array is of the length of the resulting bytes.

Parameters:

src - the byte array to encode

Returns:

A newly-allocated byte array containing the resulting encoded bytes.

注意 return 类型是 byte[].

当您将对象与字符串连接时,如

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

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

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

The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method. String conversions are implemented through the method toString, defined by Object and inherited by all classes in Java.

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

因此:

(client) MAC [B@7563b5d

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

如果要打印 Java 基本数组(例如 byte[] 数组)的 CONTENTS您需要使用 java.util.Arrays.toString() method.

之一