Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java HmacSHA256 verification: reject a changed message

Last updated: 5 Oct 20264 min read
tutorial
AdvancedBy AITrove Editorial

HMAC authenticates bytes using a secret key shared by the signer and verifier.

Verify the exact serialized message

The verifier must calculate the MAC over the same byte sequence the signer used. Reformatting a timestamp or changing whitespace before verification changes the message. This fixture generates a process-local key, signs one dispatch record, then shows that a changed record does not match.

The key exists only for this run. Production key creation, storage, access control, rotation, and version tags need a separate design. A digest alone cannot provide this origin check; SHA-256 byte hashing covers the distinction.

Frame multiple fields

Concatenating variable-length fields without boundaries can make different records produce identical MAC input bytes. Field framing gives a small counterexample. Keep the algorithm identifier and key version with stored tags so verification can select the right key after rotation.

Working program

Java
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;

public class DispatchRecordMac {
    static byte[] tag(SecretKey key, String record) throws Exception {
        Mac signer = Mac.getInstance("HmacSHA256");
        signer.init(key);
        return signer.doFinal(record.getBytes(StandardCharsets.UTF_8));
    }

    public static void main(String[] args) throws Exception {
        KeyGenerator generator = KeyGenerator.getInstance("HmacSHA256");
        SecretKey key = generator.generateKey();
        byte[] storedTag = tag(key, "dispatch=R-47");
        System.out.println("accepted=" + MessageDigest.isEqual(storedTag, tag(key, "dispatch=R-47")));
        System.out.println("tampered=" + MessageDigest.isEqual(storedTag, tag(key, "dispatch=R-48")));
    }
}

Output

Output
accepted=true
tampered=false

Cost and ownership

MAC computation processes O(n) message bytes and returns a fixed-size tag; the example allocates text bytes and tag arrays. Verification cost is small compared with key lifecycle risk. Do not log the key or treat a test-generated ephemeral key as persistent configuration.

Common Mistakes

  • Do not compare a tag over one serialization with a different serialization.
  • Do not hard-code a production HMAC key in source.
  • Do not confuse HMAC with encryption; the message remains readable.

Read next

hmac field framing, Java SHA-256: hash declared bytes, not an implicit string encoding, secure random token encoding, Java HTTPS project: a trusted local certificate and a rejected hostname.

Continue with: Java ZIP CRC32: detect corruption without claiming authenticity.

java
cryptography
hmac-sha256-verify
Storage details