Skip to content

Instantly share code, notes, and snippets.

@lounagen
Forked from thomasdarimont/readme.md
Last active April 12, 2023 00:43
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save lounagen/bdcf3e59122e80bae6da114352d0280c to your computer and use it in GitHub Desktop.
Save lounagen/bdcf3e59122e80bae6da114352d0280c to your computer and use it in GitHub Desktop.
Example for decoding a JWT Payload with your Shell (bash, zsh...)

Setup

Add this to your .profile, .bashrc, .zshrc...

BASE64_DECODER_PARAM="-d" # option -d for Linux base64 tool
echo AAAA | base64 -d > /dev/null 2>&1 || BASE64_DECODER_PARAM="-D" # option -D on MacOS

decode_base64_url() {
  local len=$((${#1} % 4))
  local result="$1"
  if [ $len -eq 2 ]; then result="$1"'=='
  elif [ $len -eq 3 ]; then result="$1"'='
  fi
  echo "$result" | tr '_-' '/+' | base64 $BASE64_DECODER_PARAM
}

decode_jose(){
   decode_base64_url $(echo -n $2 | cut -d "." -f $1) | jq .
}

decode_jwt_part(){
   decode_jose $1 $2 | jq 'if .iat then (.iatStr = (.iat|todate)) else . end | if .exp then (.expStr = (.exp|todate)) else . end | if .nbf then (.nbfStr = (.nbf|todate)) else . end'
}

decode_jwt(){
   decode_jwt_part 1 $1
   decode_jwt_part 2 $1
}

# Decode JWT header
alias jwth="decode_jwt_part 1"

# Decode JWT Payload
alias jwtp="decode_jwt_part 2"

# Decode JWT header and payload
alias jwthp="decode_jwt"


# Decode JWE header
alias jweh="decode_jose 1"

Usage

  • Compute a dummy sample JWT
HEADER=$(cat << EOF |
{
  "kid": "MY_KEY_ID",
  "alg": "RS256"
}
EOF
base64)

PAYLOAD=$(cat << EOF |
{
  "iss": "MY_ISSUER",
  "aud": "MY_AUDIENCE",
  "exp": 1547031984,
  "jti": "AMaPLqDeRizB_WP161AK8w",
  "iat": 1547024784,
  "nbf": 1547024664,
  "sub": "MY_SUBJECT"
}
EOF
base64)

SIGNATURE=FOOBAR==
  • Print the JWT header and payload
JWT=$HEADER.$PAYLOAD.$SIGNATURE

echo JWT Header:
jwth $JWT

echo JWT Payload:
jwtp $JWT

echo JWT Header and Payload:
jwthp $JWT

Output

JWT Header:
{
  "kid": "MY_KEY_ID",
  "alg": "RS256"
}
JWT Payload:
{
  "iss": "MY_ISSUER",
  "aud": "MY_AUDIENCE",
  "exp": 1547031984,
  "jti": "AMaPLqDeRizB_WP161AK8w",
  "iat": 1547024784,
  "nbf": 1547024664,
  "sub": "MY_SUBJECT",
  "iatStr": "2019-01-09T09:06:24Z",
  "expStr": "2019-01-09T11:06:24Z",
  "nbfStr": "2019-01-09T09:04:24Z"
}
JWT Header and Payload:
{
  "kid": "MY_KEY_ID",
  "alg": "RS256"
}
{
  "iss": "MY_ISSUER",
  "aud": "MY_AUDIENCE",
  "exp": 1547031984,
  "jti": "AMaPLqDeRizB_WP161AK8w",
  "iat": 1547024784,
  "nbf": 1547024664,
  "sub": "MY_SUBJECT",
  "iatStr": "2019-01-09T09:06:24Z",
  "expStr": "2019-01-09T11:06:24Z",
  "nbfStr": "2019-01-09T09:04:24Z"
}
@sahlouls
Copy link

sahlouls commented Jan 9, 2019

On Linux: update base64 -D to base64 -d as -D only works on MacOS

@lounagen
Copy link
Author

lounagen commented Jan 9, 2019

On Linux: update base64 -D to base64 -d as -D only works on MacOS

Thanks @sahlouls, i've just updated with a workaround to be compliant on linux, mac, mac with linux base64 tool :)

@mvmn
Copy link

mvmn commented Sep 3, 2019

macOS ZSH - got error decode_base64_url:6: command not found: base64 -D
Changed BASE64_DECODER to BASE64_DECODER_PARAM like this:

BASE64_DECODER_PARAM="-d" # option -d for Linux base64 tool
echo AAAA | base64 -d > /dev/null 2>&1 || BASE64_DECODER_PARAM="-D" # option -D on MacOS

decode_base64_url() {
  local len=$((${#1} % 4))
  local result="$1"
  if [ $len -eq 2 ]; then result="$1"'=='
  elif [ $len -eq 3 ]; then result="$1"'='
  fi
  echo "$result" | tr '_-' '/+' | base64 $BASE64_DECODER_PARAM
}

Works like a charm now :-)

@lounagen
Copy link
Author

lounagen commented Sep 3, 2019

Thanks @mvmn for your feedback, i updated the current gist version with your command/param split

@hangxingliu
Copy link

@lounagen I tested the flag --decode, it works both on the macOS, Ubuntu and CentOS.

@amperxand
Copy link

This is wonderful. Thank you so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment