Base64 encoding of content during VerifyJWS policy execution with "DetachedContent"

When using the VerifyJWS policy with "DetachedContent", is the payload/content still base64 encoded when apigee generates the hash that is used to verify the JWS signature?

Solved Solved
1 6 1,315
1 ACCEPTED SOLUTION

Yes.

This is a good question. Let me provide some additional background. I have a hard time being brief sometimes. This might be one of those times. I may provide more information than you asked for, but I want to do that in case anyone else has a similar question about JWS

JWS, JSON Web Signing, is described in IETF RFC 7515. It is part of the "JOSE" suite of standards, JOSE stands for JSON Object Signing and Encryption. Here's the list:

moniker name RFC
JWS JSON Web Signing 7515
JWE JSON Web Encryption 7516
JWK JSON Web Key 7517
JWA JSON Web Algorithm 7518
JWT JSON Web Token 7519

The JWS spec, specifically in Section 5.1, describes how to compute and verify a JWS. Processors must construct the hash on the result of:

  • the base64 encoded header,
  • dot-concatenated with
  • the base64-encoded payload

We can call the result of those steps as "the signature base". The has is performed on that signature base.

Verifying the signature would follow the same pattern.

Appendix F in that specification describes how to serialize with detached content. Serialization is independent of encoding or computing the signature.

So to answer your specific question, yes, VerifyJWS will base64-encode the payload, prior to constructing the signature base, when verifying the signature on a JWS with detached content.

View solution in original post

6 REPLIES 6

Yes.

This is a good question. Let me provide some additional background. I have a hard time being brief sometimes. This might be one of those times. I may provide more information than you asked for, but I want to do that in case anyone else has a similar question about JWS

JWS, JSON Web Signing, is described in IETF RFC 7515. It is part of the "JOSE" suite of standards, JOSE stands for JSON Object Signing and Encryption. Here's the list:

moniker name RFC
JWS JSON Web Signing 7515
JWE JSON Web Encryption 7516
JWK JSON Web Key 7517
JWA JSON Web Algorithm 7518
JWT JSON Web Token 7519

The JWS spec, specifically in Section 5.1, describes how to compute and verify a JWS. Processors must construct the hash on the result of:

  • the base64 encoded header,
  • dot-concatenated with
  • the base64-encoded payload

We can call the result of those steps as "the signature base". The has is performed on that signature base.

Verifying the signature would follow the same pattern.

Appendix F in that specification describes how to serialize with detached content. Serialization is independent of encoding or computing the signature.

So to answer your specific question, yes, VerifyJWS will base64-encode the payload, prior to constructing the signature base, when verifying the signature on a JWS with detached content.

Thank you for the detailed explanation. That confirms why we are having issues for a consumer of some of our APIs that use JWS tokens. I had a look at their code which uses jose4j to generate the JWS token and noticed that they are using JWS with Detached and Unencoded Payload (RFC7797). The token header "b64" is set to false and also added to the "crit" header. Your answer confirms that the "signature base" is constructed differently (unencoded payload) on their end than in Apigee (encoded payload), hence the VerifyJWS error we're seeing.


Does the VerifyJWS policy support Detached and Unencoded Payload (RFC7797) via some config parameter that I might be missing?

VerifyJWS does not support RFC7797 ! Unfortunately. I was not aware this possibility existed.

I'll log a feature request to support that. (ref b/158204922)

In the meantime you will have to resort to a workaround. I can think of these 2:

  1. Tell the signer to base64 encode the payload. This may be infeasible because of the inefficiency.
  2. Build and use a Java callout that does the right thing for Verifying JWS with Unencoded payload (RFC 7797)

Thank you for adding the feature request.

We used the first option as a workaround. Luckily the API payloads are small in size so the base64 encoding has very little performance impact.

Thanks again for the assistance!

@Dino-at-Google:

We are doing similar for open banking using PS256 alg.

https://openbankinguk.github.io/read-write-api-site3/v3.1.6/profiles/read-write-data-api-profile.htm...

x-jws-signature -> Able to detach content but having challenges in verification. Need some guidance and let me know how can I share the code..It could be something simple but not able to understand why verify is returning false.

Ref:

https://medium.com/syntaxa-tech-blog/open-banking-message-signing-b4ab4f7f92d1

https://medium.com/syntaxa-tech-blog/more-open-banking-message-signing-fe461f0a627d

Below is the JWSObject class where it is having issues..Verify will be

true if the signature was successfully verified, false if the signature is invalid or if a critical header is neither supported nor marked for deferral to the application.

public synchronized boolean verify(JWSVerifier verifier) throws JOSEException {
this.ensureSignedOrVerifiedState(); boolean verified; try {
verified = verifier.verify(this.getHeader(), this.getSigningInput(), this.getSignature());} catch (JOSEException var4) {
throw var4;} catch (Exception var5) {
throw new JOSEException(var5.getMessage(), var5);}

if (verified) {
this.state = JWSObject.State.VERIFIED;}

return verified;}

Hi Vinay

First, this sounds like a new question. But you've posted it as a buried comment in an existing 4-month old question question. That's not a good way to go. Things get lost and confused that way.

Sounds like you're doing something with JWS using PS256.

What exactly? you said "something similar" but ... no further details. Are you using the "detached and unencoded" option? If so, how? Are you base-64 encoding the payload? Using a Java callout to generate the JWS, or using GenerateJWS policy?

You said "able to detach content", ok that's good.

When a verification fails, there could be many reasons.

  • wrong key
  • wrong signature - can be because the detached content has been modified, or because it was base64 encoded during signing, but not base64 encoded during verification
  • unhandled crit header - eg, the b64 header

Without further information, there's no way for us to know what problem you might be having.

do me a favor, Post a new question, will you? with details.