JWT Consist of 3 parts:
- Header
- Data
- Verification
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header:
{
"alg": "HS256",
"typ": "JWT"
}
Strip all whitespace characters
{"alg":"HS256","typ":"JWT"}
Then base64 encode this. e.g using Python
import base64
header = '{"alg":"HS256","typ":"JWT"}'.encode('utf-8')
base64.urlsafe_b64encode(header).decode('utf-8').strip()
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Data:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Strip then base64 encode then remove all padding.
import base64
data = '{"sub":"1234567890","name":"John Doe","iat":1516239022}'.encode('utf-8')
base64.urlsafe_b64encode(data).decode('utf-8').strip().replace("=","")
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
Verification:
From the header it's define by "alg": "HS256"
which is short for HMAC SHA 256
To generate the verification signature, just concatenate both base64 encoded header and data seperated with '.'
character from previous result as the payload, then passing it to hmac function then base64 encode it.
import base64
import hashlib
import hmac
def hs256(payload):
secret = 'your-256-bit-secret'.encode('utf-8')
digest = hmac.new(secret, payload.encode('utf-8'), digestmod=hashlib.sha256).digest()
return base64.urlsafe_b64encode(digest).decode('utf-8').strip().replace('=','')
payload = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ'
hs256(payload)
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c