JWS with HMAC protection
This is an example how to create and verify a JWS encoded object with a hash-based message authentication code (HMAC). The producer and consumer must posses a shared secret, negotiated through some out-of-band mechanism before the JWS-protected object is communicated (unless the producer secures the JWS object for itself).
The payload is a simple “Hello, world!” string but can also be a JSON string or BASE64URL encoded data.
The Nimbus JOSE+JWT library supports all standard JWS algorithms for HMAC protection (note the minimum secret length requirement):
- HS256 - HMAC with SHA-256, requires 256+ bit secret
- HS384 - HMAC with SHA-384, requires 384+ bit secret
- HS512 - HMAC with SHA-512, requires 512+ bit secret
Example code:
import java.security.SecureRandom;
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.*;
// Generate random 256-bit (32-byte) shared secret
SecureRandom random = new SecureRandom();
byte[] sharedSecret = new byte[32];
random.nextBytes(sharedSecret);
// Create HMAC signer
JWSSigner signer = new MACSigner(sharedSecret);
// Prepare JWS object with "Hello, world!" payload
JWSObject jwsObject = new JWSObject(new JWSHeader(JWSAlgorithm.HS256), new Payload("Hello, world!"));
// Apply the HMAC
jwsObject.sign(signer);
// To serialize to compact form, produces something like
// eyJhbGciOiJIUzI1NiJ9.SGVsbG8sIHdvcmxkIQ.onO9Ihudz3WkiauDO2Uhyuz0Y18UASXlSc1eS0NkWyA
String s = jwsObject.serialize();
// To parse the JWS and verify it, e.g. on client-side
jwsObject = JWSObject.parse(s);
JWSVerifier verifier = new MACVerifier(sharedSecret);
assertTrue(jwsObject.verify(verifier));
assertEquals("Hello, world!", jwsObject.getPayload().toString());