Skip to content

Instantly share code, notes, and snippets.

@suhussai
Last active November 19, 2023 18:59
Show Gist options
  • Save suhussai/b441141f32f0ca7f612b11ee4c2c3caa to your computer and use it in GitHub Desktop.
Save suhussai/b441141f32f0ca7f612b11ee4c2c3caa to your computer and use it in GitHub Desktop.
JWT Decoding with Bash

JWT Decoding with Bash

Json Web Tokens (JWTs) are base64 encoded strings. This is an example of JWT pulled from jwt.io

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

It consists of three parts separated by a period ("."):

  1. Header - eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
  2. Payload - eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
  3. Signature - SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

To decode using Bash, we can decode those three parts as a single string or separately:

Decoding as a Single String

To decode the JWT from before:

$ echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" | base64 --decode --ignore-garbage
{"alg":"HS256","typ":"JWT"}{"sub":"1234567890","name":"John Doe","iat":1516239022}���pD��x�����
Lx�����"Ui�,�\%

As you can see, we have the header, payload, and signature displayed one after the other in the output.

Note that:

The last section in the JWT, the signature, is also base64-url encoded, but it’s just binary data; if you try to decode it, you will end up with non-displayable characters:

https://developer.okta.com/blog/2020/12/21/beginners-guide-to-jwt

If you omit the --ignore-garbage argument when decoding using base64, you might only see the decoded header:

$ echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" | base64 --decode
{"alg":"HS256","typ":"JWT"}base64: invalid input

Decoding Separately

Header

Here's the header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

To decode:

$ echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" | base64 --decode --ignore-garbage
{"alg":"HS256","typ":"JWT"}

Payload

Here's the payload: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

To decode:

$ echo "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ" | base64 --decode --ignore-garbage
{"sub":"1234567890","name":"John Doe","iat":1516239022}base64: invalid input

(Why does it say 'invalid input')

Signature

Here's the signature: SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

To decode:

$ echo "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" | base64 --decode --ignore-garbage
I�J�IHNJ(]�O��lj�~�:N�%V�B�0�base64: invalid input
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment