Skip to content

Instantly share code, notes, and snippets.

@jamesmartin
Created June 1, 2021 22:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesmartin/7077f0f786295f6690894f99ade4d5b3 to your computer and use it in GitHub Desktop.
Save jamesmartin/7077f0f786295f6690894f99ade4d5b3 to your computer and use it in GitHub Desktop.
Bash JWT Encoder
#!/usr/bin/env bash
#
# JWT Encoder Bash Script
#
secret='SOME SECRET'
# Static header fields.
header='{
"typ": "JWT",
"alg": "HS256",
"kid": "0001",
"iss": "Bash JWT Generator"
}'
# Use jq to set the dynamic `iat` and `exp`
# fields on the header using the current time.
# `iat` is set to now, and `exp` is now + 1 second.
header=$(
echo "${header}" | jq --arg time_str "$(date +%s)" \
'
($time_str | tonumber) as $time_num
| .iat=$time_num
| .exp=($time_num + 1)
'
)
payload='{
"Id": 1,
"Name": "Hello, world!"
}'
base64_encode()
{
declare input=${1:-$(</dev/stdin)}
# Use `tr` to URL encode the output from base64.
printf '%s' "${input}" | base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n'
}
json() {
declare input=${1:-$(</dev/stdin)}
printf '%s' "${input}" | jq -c .
}
hmacsha256_sign()
{
declare input=${1:-$(</dev/stdin)}
printf '%s' "${input}" | openssl dgst -binary -sha256 -hmac "${secret}"
}
header_base64=$(echo "${header}" | json | base64_encode)
payload_base64=$(echo "${payload}" | json | base64_encode)
header_payload=$(echo "${header_base64}.${payload_base64}")
signature=$(echo "${header_payload}" | hmacsha256_sign | base64_encode)
echo "${header_payload}.${signature}"
@jamesmartin
Copy link
Author

@shkpk
Copy link

shkpk commented Jul 21, 2022

encoder returns error when using empty payload
payload='{}'

+++ openssl dgst -binary -sha256 -hmac GCBsn2MC8KBBcocP26NasH2K3bvDMDSW7wYXayrDv5xUp49IQ24Q
test.sh: line 21: warning: command substitution: ignored null byte in input
�"Z��*�ko��+'input=])�c�`�
            ����'
�"Z��*�ko��+s '])�c�`�
            ����'

@shkpk
Copy link

shkpk commented Jul 21, 2022

encoder returns error when using empty payload payload='{}'

+++ openssl dgst -binary -sha256 -hmac GCBsn2MC8KBBcocP26NasH2K3bvDMDSW7wYXayrDv5xUp49IQ24Q
test.sh: line 21: warning: command substitution: ignored null byte in input
�"Z��*�ko��+'input=])�c�`�
            ����'
�"Z��*�ko��+s '])�c�`�
            ����'
#!/bin/bash
token_gen() {
    secret=$1
    header='{
        "typ": "JWT",
        "alg": "HS256",
        "kid": "0001",
        "iss": "Bash JWT Generator"
    }'
    header=$(
        echo "${header}" | jq --arg time_str "$(date +%s)" \
        '
        ($time_str | tonumber) as $time_num
        | .iat=$time_num
        | .exp=($time_num + 1)
        '
    )
    payload='{}'
    #shellcheck disable=2120
    base64_encode() {
        declare input=${1:-$(</dev/stdin)}
        printf '%s' "${input}" | base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n'
    }
    #shellcheck disable=2120
    json() {
        declare input=${1:-$(</dev/stdin)}
        printf '%s' "${input}" | jq -c .
    }
    #shellcheck disable=2120
    hmacsha256_sign() {
        declare input=${1:-$(</dev/stdin)}
        printf '%s' "${input}" | openssl dgst -binary -sha256 -hmac "${secret}"
    }
    header_base64=$(echo "${header}" | json | base64_encode)
    payload_base64=$(echo "${payload}" | json | base64_encode)
    #shellcheck disable=2116
    header_payload=$(echo "${header_base64}.${payload_base64}")
    signature=$(echo "${header_payload}" | hmacsha256_sign | base64_encode)
    echo "${header_payload}.${signature}"
}

SECRET_KEY=GCBsn2MC8KBBcocP26NasH2K3bvDMDSW7wYXayrDv5xUp49IQ24Q
AUTH_TOKEN=$(token_gen "$SECRET_KEY")
echo $AUTH_TOKEN

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