简体   繁体   中英

Java HMAC returns different mac when called on same value

When trying to use HMAC to get a mac for validating the authenticity of a request my function always returns a different mac which means I cannot use that mac is there something I am missing?

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;
    }

algorithm key and message are always the same when I call them. With the algorithm being "HmacSHA256"

output:

(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

You are implicitly using the toString() method of Java byte[] arrays.

From 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.

Note that the return type is byte[] .

When you concatenate an object with a string, as in

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

you use the toString() method to convert that object to a Java String .

Per theString Java documentation (bolding mine):

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.

The toString() method for a Java primitive array prints the type of the array and then it's address.

Thus:

(client) MAC [B@7563b5d

The [B means " byte[] array" and the @7563b5d is likely the address (or some other JVM accounting tag) for the byte[] Java Object .

If you want to print the CONTENTS of a Java primitive array such as a byte[] array you need to use one of the java.util.Arrays.toString() method .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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