Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have a JWT token generated by some service and then being verified on my Java application.

The problems is that JJWT library fails to parse JSON header due to wrong decoding of base64.

Header Base64 code: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InRva2VuLXNpZ25pbmcifQ

Decoded by JJWT (boils down to calling: new String(javax.xml.bind.DatatypeConverter.parseBase64Binary(myBase64), java.nio.charset.Charset.forName("UTF-8"))) ):

{"alg":"RS256","typ":"JWT","kid":"token-signing"

So the last curly brace is lost.

However when I tried ше with other decoder (https://www.base64decode.org/) - the last curly brace is in place.

Also for other developer the same code used to work.

Can it be something environment specific which influences Base64 decoding in Java?

The header you received is Base64 without output padding (note that there are 66 characters, which is not a multiple of 4). DatatypeConverter.parseBase64Binary is specified to parse the XML Schema xsd:base64Binary type, which requires output padding. Apparently it treats the non-padded characters at the end as invalid and simply ignores them.

Either use a different decoder (Java 8 has java.util.Base64, Apache Commons.Codec has one, Guava has one too), or pad the output yourself (if length of string after removing all non-Base64 characters is not divisible by 4, pad with '=' until it is).

The header and payload of a JWT is base64 url encoded, which is slightly different than base64 (replaces +, \ with -,_ and removes trailing =)

Using this code DatatypeConverter.parseBase64Binary to decode the header is wrong. It is needed to use:

java.util.Base64.getUrlDecoder().decode(string);

I have reviewed the code of JJWT and decodes the header in the correct way. Look at DefaultJWTSParser line 255

String origValue = TextCodec.BASE64URL.decodeToString(base64UrlEncodedHeader);

May be you are using other library?

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.