I'm trying to write some code to sign and validate payloads using my private/public keys in java following JOSE standards. I need to use the PS256 encryption algorithm for this.
I'm using connect2id's library Nimbus JOSE + JWT. I'm able to get to the point where I can sign a payload with a private key I load from the file system, and I can also validate it. However as part of my requirements, my header needs to have a "crit" value (explained as part of RFC-7515).
My problem is the following: As soon as I have a "crit" value in the header, my token validation fails (even if the values in the "crit" array are present in my jws header, as required by the standard). If I take out the "crit", then the signature is validated correctly.
// create RSA key used for signing.
RSAKey rsaJWK = new RSAKey.Builder(pub)
.privateKey(priv)
.keyUse(KeyUse.SIGNATURE)
.algorithm(JWSAlgorithm.PS256)
.keyID("KeyID")
.build();
// Create RSA-signer with the private key
JWSSigner signer = new RSASSASigner(rsaJWK);
// setting critical values to be used in jws header
Set crit = new HashSet();
crit.add("myHeader");
// setting additional parameters for the jws header
Map myParams = new HashMap();
myParams.put("myHeader", false);
// build the jws header with all the values needed
JWSHeader jwsHeader = new JWSHeader.Builder(JWSAlgorithm.PS256)
.type(JOSEObjectType.JOSE)
.contentType("application/json")
.keyID("KeyID")
.criticalParams(crit)
.customParams(myParams)
.build();
// build the jws object with the header we created above and a static payload for now
JWSObject jwsObject = new JWSObject(jwsHeader, new Payload("{\"message\":\"In RSA we trust!!!\"}"));
// sign the payload
jwsObject.sign(signer);
// print out the token
String s = jwsObject.serialize();
System.out.println("Your token:" + s);
// To parse the JWS and verify it, e.g. on client-side
JWSObject jwsValObj = JWSObject.parse(s);
JWSVerifier verifier = new RSASSAVerifier(pub);
// verify the signature of the parsed token
boolean sigval = jwsValObj.verify(verifier);
System.out.println("Signature Validation passed: " + String.valueOf(sigval));
I'm expecting the signature to be verified properly since the values in "crit" are present in the token given.
As soon as I remove the line with .criticalParams(crit)
, then verification goes through without a problem.
Can someone help me out with this? Am I misunderstanding something or missing some glaring detail?