Use of B64 (base64) encoded keys in VerifyJWT policy

We need to verify a JWT Token using a key which has been encoded to B64. We cannot decode the key and use the string because it contains non-printable characters (hence why it is more secure than a plain text key).

However, the JWT verify policy does not support this - adding the char refs fails because the XML does not support v1.1 with control chars - even if I feed in the decoded byte array from a javascript routine it does not work.

JWT.io shows how to support use of B64 encoded keys to verify JWT signatures - so is this an Apigee shortcoming? or is there a way of feeding in a key to the XML which B64 decodes to non-printable?

Solved Solved
1 8 1,010
1 ACCEPTED SOLUTION

is there a way of feeding in a key to the XML which B64 decodes to non-printable?

Can you try this?

<VerifyJWT name='whatever'>
  <Algorithm>HS256</Algorithm>
  <SecretKey encoding='base64'>
    <Value ref='private.secret_key_base64encoded'/>
  </SecretKey>
  ...

Permitted values for encoding are: hex, base16, base64, base64url. The first two are synonyms. If no encoding attribute is present, then the key Value is decoded into bytes as a utf-8 string. Interestingly, utf-8 is not one of the valid values you can use for encoding attribute. (This seems like a bug to me) 

I tried to do the B64 decode using javascript and feed into a variable...it does not work...

I suppose this fails because JavaScript context.setVariable() may coerce things to a string. Or, ... it's a Javascript array, which the VerifyJWT policy does not handle.

View solution in original post

8 REPLIES 8

Not applicable

did you try storing in kvm, extracting from there and use?

If that doesn't work, you can use java callout implementing the same logic of her.

I tried to do the B64 decode using javascript and feed into a variable - and while this works fine for keys which decode to printable characters - it does not work for those which decoded to non-printable making me think the actual VerifyJWT policy simply does not accept this as input.

For KVM I have not tried as I cannot see how it will work - unless I can store as B64 value and when used it arrives as decoded - but I don't think KVM works like that - and if it did - surely it would have the same issue as the javascript attempt above?

is there a way of feeding in a key to the XML which B64 decodes to non-printable?

Can you try this?

<VerifyJWT name='whatever'>
  <Algorithm>HS256</Algorithm>
  <SecretKey encoding='base64'>
    <Value ref='private.secret_key_base64encoded'/>
  </SecretKey>
  ...

Permitted values for encoding are: hex, base16, base64, base64url. The first two are synonyms. If no encoding attribute is present, then the key Value is decoded into bytes as a utf-8 string. Interestingly, utf-8 is not one of the valid values you can use for encoding attribute. (This seems like a bug to me) 

I tried to do the B64 decode using javascript and feed into a variable...it does not work...

I suppose this fails because JavaScript context.setVariable() may coerce things to a string. Or, ... it's a Javascript array, which the VerifyJWT policy does not handle.

Thanks for the suggestion Dino - unfortunately, although the XML is accepted, the signature verifies on the string of the string value (i.e. makes no difference if you add the encoding attribute or not - effect is the same)

Are you using Apigee Saas? It should work in all organizations.

If you are using OPDK, then... you need OPDK 4.50.00 or later.

If you cannot upgrade, then you need to resort to what Priyadarshi suggested: write a custom Java callout do do the key decoding that you need.

Ah! We are Apigee Edge on-prem 4.19 - so you are saying B64 is now supported, but not on our current version??

Yes, that's exactly what I'm saying. [Also: go Cloud FTW!]

Tested JWT verify with encoding='base64' and encoded key on demo SaaS Apigee and works like a charm - thanks Dino!!