Let’s Talk About JWT

Disclaimer

@jesstemporal

jesstemporal.com

@jesstemporal

jesstemporal.com

JWT

"Jot"

@jesstemporal

jesstemporal.com

JWT

JSON Object Signing and Encryption - JOSE

@jesstemporal

jesstemporal.com

RFC 7519

@jesstemporal

jesstemporal.com

Usually is a standardized string that represents information

@jesstemporal

jesstemporal.com

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiZ2l2ZW5fbmFtZSI6Ikplc3NpY2EiLCJmYW1pbHlfbmFtZSI6IlRlbXBvcmFsIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiamVzc3RlbXBvcmFsIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1NTIzMDU3MTB9.LmUNPW9fSAqVTGEEFW0yrsD9eooyRv_VPB3r6tCWkRc

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiZ2l2ZW5fbmFtZSI6Ikplc3NpY2EiLCJmYW1pbHlfbmFtZSI6IlRlbXBvcmFsIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiamVzc3RlbXBvcmFsIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1NTIzMDU3MTB9.LmUNPW9fSAqVTGEEFW0yrsD9eooyRv_VPB3r6tCWkRc

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiZ2l2ZW5fbmFtZSI6Ikplc3NpY2EiLCJmYW1pbHlfbmFtZSI6IlRlbXBvcmFsIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiamVzc3RlbXBvcmFsIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1NTIzMDU3MTB9.LmUNPW9fSAqVTGEEFW0yrsD9eooyRv_VPB3r6tCWkRc

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiZ2l2ZW5fbmFtZSI6Ikplc3NpY2EiLCJmYW1pbHlfbmFtZSI6IlRlbXBvcmFsIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiamVzc3RlbXBvcmFsIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1NTIzMDU3MTB9.LmUNPW9fSAqVTGEEFW0yrsD9eooyRv_VPB3r6tCWkRc

@jesstemporal

jesstemporal.com

{
  "alg": "HS256",
  "typ": "JWT"
}

The header

@jesstemporal

jesstemporal.com

{
  "sub": "1234567890",
  "given_name": "Jessica",
  "family_name": "Temporal",
  "preferred_username": "jesstemporal",
  "iat": 1516239022,
  "exp": 1552305710
}

The Payload

@jesstemporal

jesstemporal.com

{
  "sub": "1234567890",
  "iss": "https://jtemporal.com",
  "iat": 1516239022,
  "exp": 1552305710
}

Reserved claims

@jesstemporal

jesstemporal.com

{
  "given_name": "Jessica",
  "family_name": "Temporal",
  "preferred_username": "jesstemporal"
}

Public claims

@jesstemporal

jesstemporal.com

{
  "anything": "you want",
  "really": "anything"
}

Private claims

@jesstemporal

jesstemporal.com

HMACSHA256(
    encodeBase64(header) + "." +
    encodeBase64(payload),
    "your-256-bit-secret"
)

The Signature

@jesstemporal

jesstemporal.com

HMACSHA256(
    encodeBase64(header) + "." +
    encodeBase64(payload),
    "nPilVwFjcF0v5NL5YT1xsiwRJCGqM1do"
)

The Signature

Symmetrical algorithm

🤫

@jesstemporal

jesstemporal.com

Asymmetrical algorithm

🔑🗝

@jesstemporal

jesstemporal.com

JSON Web Key

@jesstemporal

jesstemporal.com

RFC 7517

@jesstemporal

jesstemporal.com

@jesstemporal

jesstemporal.com

JWK

{
  "keys": [{
     "alg": "RS256",
     "kty": "RSA",
     "use": "sig",
     "n": "uEOPrkjGKxE...YIwS5ZoDQ",
     "e": "AQAB",
     "kid": "n6OFo...9cl9",
     "x5t": "ET...rQA",
     "x5c": ["MIIDDTCCAf...OaeyleoS0="]
  }]
}

JWTs in Python

with PyJWT

@jesstemporal

jesstemporal.com

import jwt

token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MjQyIiwibmFtZSI6Ikplc3NpY2EgVGVtcG9yYWwiLCJuaWNrbmFtZSI6Ikplc3MifQ.izbq1mT_GXp-39o-JEm1i1W1FcYBIaX3a5c4ZwRzXhE'

jwt.decode(
  token,
  key='my_super_secret',
  algorithms=['HS256', ]
)
import jwt

token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MjQyIiwibmFtZSI6Ikplc3NpY2EgVGVtcG9yYWwiLCJuaWNrbmFtZSI6Ikplc3MifQ.izbq1mT_GXp-39o-JEm1i1W1FcYBIaX3a5c4ZwRzXhE'

jwt.decode(
  token,
  key='my_super_secret',
  algorithms=['HS256', ]
)

# {"sub": "4242", "name": "Jessica Temporal", "nickname": "Jess"}
import jwt

token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsIm5hbWUiOiJKZXNzIFRlbXBvcmFsIiwiZXhwIjoxNTE2MjM5MDIyfQ.uqeQ60enLaCQEZ-7C0d_cgQSrWfgXRQuoB1LZD0j06E'

jwt.decode(
    token,
    key='my_super_secret',
    algorithms=['HS256', ]
)
import jwt

token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsIm5hbWUiOiJKZXNzIFRlbXBvcmFsIiwiZXhwIjoxNTE2MjM5MDIyfQ.uqeQ60enLaCQEZ-7C0d_cgQSrWfgXRQuoB1LZD0j06E'

jwt.decode(
    token,
    key='my_super_secret',
    algorithms=['HS256', ]
)

# ExpiredSigureError: Signature Expired
import jwt

from cryptography.hazmat.primitives import serialization

token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI0MjQyIiwibmFtZSI6Ikplc3NpY2EgVGVtcG9yYWwiLCJuaWNrbmFtZSI6Ikplc3MifQ.HgHJPl6b5W0CiDz4cNuyRcs5B3KgaoRbMvZBgCkcXOSOCAc0m7R10tSm6d86u8oW8NgzGoIAlKxBw0CIPhdx5N7MWTE2gshzQqhuq5MB9tNX1pYrLsiOMbibeMasvcf97Kd3JiLAzPPJe6XXB4PNL4h_4RcW6aCgUlRhGMPx1eRkGxAu6ndp5zzWiHQH2KVcpdVVdAwbTznLv3OLvcZqSZj_zemj__IAZPMkBBnhdjYPn-44p9-xrNmFZ9qBth4Ps1ZC1_A6lH77Mi1zb48Ou60SUT1-dhKLU09yY3IX8Pas6xtH6NbZ-e3FxjofO_OL47p25CvdqMYW50JVit2tjU6yzaoXde8JV3J40xuQqwZeP6gsClPJTdA-71PBoAYbjz58O-Aae8OlxfWZyPsyeCPQhog5KjwqsgHUQZp2zIE0Y50CEfoEzsSLRUbIklWNSP9_Vy3-pQAKlEpft0F-xP-fkSf9_AC4-81gVns6I_j4kSuyuRxlAJBe3pHi-yS2'
import jwt

from cryptography.hazmat.primitives import serialization

token = 'eyJ0eXAiOiJK...81gVns6I_j4kSuyuRxlAJBe3pHi-yS2'

public_key = open('.ssh/id_rsa.pub', 'r').read()
import jwt

from cryptography.hazmat.primitives import serialization

token = 'eyJ0eXAiOiJK...81gVns6I_j4kSuyuRxlAJBe3pHi-yS2'

public_key = open('.ssh/id_rsa.pub', 'r').read()
key = serialization.load_ssh_public_key(public_key.encode())
import jwt

from cryptography.hazmat.primitives import serialization

token = 'eyJ0eXAiOiJK...81gVns6I_j4kSuyuRxlAJBe3pHi-yS2'

public_key = open('.ssh/id_rsa.pub', 'r').read()
key = serialization.load_ssh_public_key(public_key.encode())

jwt.decode(jwt=token, key=key, algorithms=['RS256', ])

# {'sub': '4242', 'name': 'Jessica Temporal', 'nickname': 'Jess'}

Where to find JWTs?

@jesstemporal

jesstemporal.com

Access token

@jesstemporal

jesstemporal.com

RFC 9068

@jesstemporal

jesstemporal.com

ID token

@jesstemporal

jesstemporal.com

 How to be safer with JWTs

@jesstemporal

jesstemporal.com

 Don't store JWTs in local storage

@jesstemporal

jesstemporal.com

 Don't verify access tokens in the front end

@jesstemporal

jesstemporal.com

Keep it small,

only relevant data

@jesstemporal

jesstemporal.com

 Don't put sensitive data in the JWT

@jesstemporal

jesstemporal.com

Tools

@jesstemporal

jesstemporal.com

jwt.io

 

@jesstemporal

jesstemporal.com

@jesstemporal

jesstemporal.com

Questions?!

PyBay - Let’s Talk About JWT

By Jessica Temporal

PyBay - Let’s Talk About JWT

JSON Web Tokens, or JWTs for short, are all over the web. They can be used to track bits of information about a user in a very compact way and can be used in APIs for authorization purposes. Join me and learn what JWTs are, what problems it resolves, and how you can use JWTs on your applications.

  • 266