8

In Notepad++, I'm having trouble decoding a JWT. When I try to use Plugins -> MIME Tools -> Base64 Decode with:

eyJleHAiOjE0NDIzNjAwMzQsIm5iZiI6MTQ0MjM1NjQzNCwidmVyIjoiMS4wIiwiaXNzIjoiaHR0cHM6Ly9sb2dpbi5taWNyb3NvZnRvbmxpbmUuY29tLzc3NTUyN2ZmLTlhMzctNDMwNy04YjNkLWNjMzExZjU4ZDkyNS92Mi4wLyIsImFjciI6ImIyY18xX3NpZ25faW5fc3RvY2siLCJzdWIiOiJOb3Qgc3VwcG9ydGVkIGN1cnJlbnRseS4gVXNlIG9pZCBjbGFpbS4iLCJhdWQiOiI5MGMwZmU2My1iY2YyLTQ0ZDUtOGZiNy1iOGJiYzBiMjlkYzYiLCJpYXQiOjE0NDIzNTY0MzQsImF1dGhfdGltZSI6MTQ0MjM1NjQzNCwiaWRwIjoiZmFjZWJvb2suY29tIn0

I get:

Length of selected text (not including EOL) to be decoded is invalid. It should be mod 4.

But if use www.base64decode.org it works fine:

{"exp":1442360034,"nbf":1442356434,"ver":"1.0","iss":"https://login.microsoftonline.com/775527ff-9a37-4307-8b3d-cc311f58d925/v2.0/","acr":"b2c_1_sign_in_stock","sub":"Not supported currently. Use oid claim.","aud":"90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6","iat":1442356434,"auth_time":1442356434,"idp":"facebook.com"}

Why is that? Am I using Notepad++ incorrectly?


The value I'm using came from Azure AD B2C: Token reference.


Update 2020/01/28

I just tried the above JWT and Plugins -> MIME Tools -> Base64 Decode is able to handle this use case now . I'm on v2.5 of the plugin. I'm guessing v2.2 "fixed" this:

Npp mime tools v2.2 release
donho released this on Nov 28, 2018
Enhance base64: decode/encode without padding

spottedmahn
  • 14,823
  • 13
  • 108
  • 178
  • 2
    The `=` at the end of the data have been removed. Just add one or two and retry. – Spomky-Labs Nov 05 '17 at 03:11
  • @FlorentMorselli that was it! please provide an answer and I'll mark it as such – spottedmahn Nov 06 '17 at 14:48
  • 1
    `base64 -d` command on Linux decodes JWT parts (starting from `eyJ` and ending to the next `.`) successfully without having to add `=`. It just displays the error message `base64: invalid input` if an `=` is missing at the end. – baptx Jun 07 '19 at 08:01

3 Answers3

9

Short answer:

To make the string decodable you have to make the number of characters in the encoded string an integer multiple of 4. Meaning you have to divide the number of characters by 4 and not get a remainder. In this particular case, you have 443 characters. Adding a = at the end will make it decodable.

Long answer:

Base64 encoding uses something called padding. The number of characters in the output has to be an integer multiple of 4. If the actual output doesn't fulfill that requirement the encoding algorithm will add additional padding characters to the output. The padding character is usually =.

There are some examples on Wikipedia of how this works. You can also see this SO post.

There is a difference between "ordinary" base64url encoding, and the base64url encoding used with JWT: JWT skips the padding characters. They are simply not added. So any decoding algorithm for JWT has to take that fact into account.

Ordinary base64 decoders will not allow encoded strings without padding, as input (if padding was required). Most decoders have an assertion at the beginning of the decoding algorithm where they check the length of the input string and check that the length % 4 = 0. You can see that from the error message

Length of selected text (not including EOL) to be decoded is invalid. It should be mod 4.

The length is wrong because the padding characters are missing.

So using decoders that handle padless strings is the way to go. Andre already linked one site. Here is another.

Mika Sundland
  • 18,120
  • 16
  • 38
  • 50
  • I see, thanks Mike! I added an `=` to the start and I don't get the error but the data is garbage. I also performed a `URL Decode` first for Chris's answer. – spottedmahn Nov 06 '17 at 14:20
  • 1
    @spottedmahn I copy/pasted your encoded string and added a `=` to make it 444 characters, which is dividable by 4. The decoded content looks fine to me, but the actual content is slightly different from what you have in the question. I had to select the content I wanted to decode. – Mika Sundland Nov 06 '17 at 14:42
  • I prepended the `=` and that failed. After reading your response, I tried appending it and that worked! – spottedmahn Nov 06 '17 at 14:49
  • You're right about the encoded token. I put in the wrong one. I've updated the question, thanks! – spottedmahn Nov 06 '17 at 14:53
  • 1
    @spottedmahn Ok, that's good. I provided a shorter version on top of my answer to make it more applicable to this particular case. – Mika Sundland Nov 06 '17 at 14:59
  • Perfect. I appreciate the short and longer version! The short one is perfect to try the fix. The long one is perfect to continue my education. – spottedmahn Nov 06 '17 at 15:05
8

JWT are encoded using "base64url" which uses a URL-safe alphabet.

The "base64url" encoding is the Base 64 encoding where URL-reserved characters are replaced (e.g. - replaces + and _ replaces /) and the padding characters are removed.

Community
  • 1
  • 1
Chris Padgett
  • 14,186
  • 1
  • 15
  • 28
2

The token above is not the same in the Azure B2C doc indicated and it seems invalid. Unless this question is about Notepad++, I'd recommend using a site like https://jwt.ms to decode tokens. jwt.ms helps you not only decode the token but also understand what each one of claims means.

Andre Teixeira
  • 783
  • 3
  • 11
  • "seems invalid" it is just the [`payload` portion](https://scotch.io/tutorials/the-anatomy-of-a-json-web-token#toc-breaking-down-a-json-web-token). – spottedmahn Nov 03 '17 at 19:54