Pretty Printing JSON Web Tokens (JWTs) on the Command Line using OpenSSL

Let's say you're starting to work with JWTs, and to confirm that their payload is correct, you want to introspect their contents. However, you may be aware that JWTs can contain sensitive information such as the hostname of a server, personally identifiable information, or could be used as a bearer token to access a service, so you shouldn't really be introspecting it in some public space such as JWT.io.

This has put you in a difficult position, but no more - decoding a JWT is really easy, and in this example I'll show you how to do it using just GNU Bash and OpenSSL for a dependency-less alternative to using Ruby.

Let us use the following JWT in example.jwt, via JWT.io:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWTs have a couple of characteristics that we need to be aware of - they can be URL encoded (RFC7515) and they Base64 encoding will need to padded out so OpenSSL can read it properly.

We don't care about looking at the signature, only the header and payload, so just want to pull out the first two pieces and output them:

function jwt() {
  for part in 1 2; do
    b64="$(cut -f$part -d. <<< "$1" | tr '_-' '/+')"
    len=${#b64}
    n=$((len % 4))
    if [[ 2 -eq n ]]; then
      b64="${b64}=="
    elif [[ 3 -eq n ]]; then
      b64="${b64}="
    fi
    openssl enc -base64 -d <<< "$b64"
    echo
  done
}

Note that we add the extra echos so we have newlines between the decoded objects:

{"alg":"HS256","typ":"JWT"}
{"sub":"1234567890","name":"John Doe","iat":1516239022}

But that doesn't look so pretty, especially when we have large JSON objects. So instead for an almost dependency-less script, we can use Python to pretty-print the JSON:

function jwt() {
  for part in 1 2; do
    b64="$(cut -f$part -d. <<< "$1" | tr '_-' '/+')"
    len=${#b64}
    n=$((len % 4))
    if [[ 2 -eq n ]]; then
      b64="${b64}=="
    elif [[ 3 -eq n ]]; then
      b64="${b64}="
    fi
    openssl enc -base64 -d <<< "$b64" | python -mjson.tool
  done
}

Which then outputs:

{
    "alg": "HS256",
    "typ": "JWT"
}
{
    "sub": "1234567890",
    "name": "John Doe",
    "iat": 1516239022
}

Written by Jamie Tanna on , and last updated on .

Content for this article is shared under the terms of the Creative Commons Attribution Non Commercial Share Alike 4.0 International, and code is shared under the Apache License 2.0.

Categories
Tags
Related Posts

Other posts you may be interested in:

Interactions with this post

Interactions with this post

This post has had 0 WebMention interactions, as of Mon, 17 Jun 2019 20:23:26 +0100.

Have you written a response to this post? Let me know the URL: