Connaissez-vous vraiment JWT ?
A propos
de moi

Karim Pinchon
- Développeur backend
- @kpn13
- https://blog.karimpinchon.com



Quelques
concepts
de base

Jeton / Token

C'est quoi un jeton ?
- chaine de caractères
- authentification
- autorisation
- ...
ça a quelle forme ?
ça sert à quoi ?

Une simple chaine ?


Référence
Valeur

JSON Web Token

https://jwt.io/
JSON Web Token
"JOT"

The suggested pronunciation of JWT is the same as the English word "jot".
RFC 7519
La cryptographie

C'est quoi la cryptographie ?
- mathématiques
- confiance
- communication
- canal non sûr
- CAIN (entre autres)

Signature numérique
- intégrité
- authentification
- non répudiation

Chiffrement
- confidentialité

Hachage
- intégrité
- sens unique

MAC / HMAC
- MAC (Message Authentication Code)
- HMAC (Hash-Based ...)
- intégrité
- authentification

Encodage
- registre de caractères

A quoi ça ressemble?


jwt.io
token.dev

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJteSBzZXJ2ZXIiLCJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkthcmltIFBJTkNIT04iLCJpYXQiOjE2MTk4NjI0NzUsImF1ZCI6IkFGVVBEYXkgTGlsbGUvUmVubmVzIDIwMjEiLCJleHAiOjE2MjIyNDYzOTksImp0aSI6IjdhMzY1ZGQwLTdiYzctNDg5NC1iYjA5LTc3MWVhMTUyY2M1NSJ9.KqQZVQdyxIv70mc2U2f78g41IVr94GHU_JM7LYBMxqU
JSON Web Token (JWT)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJteSBzZXJ2ZXIiLCJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkthcmltIFBJTkNIT04iLCJpYXQiOjE2MTk4NjI0NzUsImF1ZCI6IkFGVVBEYXkgTGlsbGUvUmVubmVzIDIwMjEiLCJleHAiOjE2MjIyNDYzOTksImp0aSI6IjdhMzY1ZGQwLTdiYzctNDg5NC1iYjA5LTc3MWVhMTUyY2M1NSJ9.KqQZVQdyxIv70mc2U2f78g41IVr94GHU_JM7LYBMxqU
JSON Web Token (JWT)
{
"alg": "HS256",
"typ": "JWT"
}
{
"iss": "my server",
"sub": "1234567890",
"name": "Karim PINCHON",
"iat": 1619862475,
"aud": "Devoxx France 2022",
"exp": 1622246399,
"jti": "7a365dd0-7bc7-4894-bb09-771ea152cc55"
}
HMACSHA256( base64UrlEncode( ) + "." + base64UrlEncode(payload), UN_SECRET)
entête
charge utile
.
.
header
signature
{
"payload":"ewogICJpc3MiOiAibXkgc2VydmVyIiwKICAic3ViIjogIjEyMzQ1Njc4OTAiLAogICJuYW1lIjogIkthcmltIFBJTkNIT04iLAogICJpYXQiOiAxNjE5ODYyNDc1LAogICJhdWQiOiAiQUZVUERheSBMaWxsZS9SZW5uZXMgMjAyMSIsCiAgImV4cCI6IDE2MjIyNDYzOTksCiAgImp0aSI6ICI3YTM2NWRkMC03YmM3LTQ4OTQtYmIwOS03NzFlYTE1MmNjNTUiCn0K",
"protected":"eyJhbGciOiJSUzI1NiJ9",
"signature":"ZbJXgzuYVCQCqoUxa5OtWRqmsl2S3Pe-29P19KacZgXlymwi-G-w6n-dnZObTPbheJbnlbptvv8yWO_pEqnohZZXH_c7Sd5sEm5k58-6GqG1FE13Q2CmWA44V91YbHA0rpMhiA1GNxVHIdNpW9wNkzEM3aqbJ9sdhix2RsbS3ofBWQdyaFSDrazWWCAK17ghI5KlUK_KQWNlXDZd8dn7VMNGBRuA5N4erfftG6i-OtFODYR_R1Eb0ltGBYOZamLOxtwR8PR40vjLGtQwJdp8CxdKXKHvrzahRA6k3YRYT2U8dzCsDPYFuzUAZgiSZ5JEG5favYWQsiyg84wF35jIdA"
}
JSON serialization format
(oui oui c'est aussi un JWT)
Focus sur l'entête
{
"typ":"JWT",
"alg":"HS256",
"jku":"https://key.service.com/keys.json",
"jwk":"...",
"kid":"ebb58a6d-0c84-4b5e-aac3-f5edc600cd77",
"x5u":"https://key.service.com/keys.pem",
"x5c":"...",
"x5t":"bcb0923eacb242cf0e69e626cd7ca2fc3426fae0",
"x5t#S256":"dbb821587583647e905b94764c86eb9f85bad06ced4087256bfcee19c7e44389",
"cty":"jwk+json",
"crit":["exp"]
}
Entête
Focus sur
la charge utile
"Registered claims"
(tout ça c'est optionnel)
{
"iss":"émetteur du jeton",
"aud":"le destinataire du jeton",
"sub":"le sujet du jeton",
"iat":"la date d'émission du jeton",
"nbf":"à partir de quelle date il est valide",
"exp":"quand le jeton expire",
"jti":"identifiant unique du jeton"
}
"Public claims"
https://www.iana.org/assignments/jwt/jwt.xhtml

"Private claims"

Go
JOSE


JOSE
Javascript Object Signing and Encryption

JSON Web Token
- RFC 7519
- "claims" entre plusieurs parties
JSON Web Signature
- RFC 7515
- jeton signé
JSON Web Encryption
- RFC 7516
- jeton chiffré
JSON Web Algorithms
- RFC 7518
- algorithmes
JSON Web Key
- RFC 7517
- clés
Voyons
JWE

JSON Web Encryption (JWE)
eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.uWmje_-Y3GF2nzjLzPopD17yHB7WBDrQgPeE011dhep40Hg4sE6-ZbqBgc4K4cwfbsXU-ZwTY5b6RiHa8clNtZZW2_Qm1Mbu8jcXs-84OrL9n9t7CgdTBd1lGp8e5j6bAxBJTjwdOWO6Cz492DVAxxNNMyuV0UIJsgEUo8b5IpLD4j2VvOgE_V8FSMuifEsq13OKORjfQ2wApIZDw1QAhXQ9GLx08Nl-0umEcaiXH8f36Pqvt4dRwK6tSIgSMht3qAXNCtBBFQS8fyffu1KyZ8_11gWlQdeisPhKbDGEDBNd2SAN2-lQxrcCBmyJ3oD0PCeS3sV8fvoM4eFRfzYhpg.lI2L7mB4nXr4Lnsk.pkdYMTeQUjmBd5kGUnLL72n4ztIQaotAsy1MQj7180sMkGzNwq9n8mI-1bhpavxgAczRhGfKXSmHfHsF3curt10ClMZOsHOJ8sP93lura_5pU7ZYB0V2stupb6a8IiWWYOdASpjtsKr0VpKRO_AuiaRGC1WZdlhWHnptIP78bkG2P7hV57ht3W-upjIErnRtEY29Vt7ddu-r983l8MLw2-8-jb31LxgJYS2Zkr7eDB-UmI5xygsEHLH_pdqOKqxJhO3U3LkWBlt7a1sH.SzRYiT21_Lv7ae8xxmmfRg
Compact serialization format
JSON Web Encryption (JWE)
eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.uWmje_-Y3GF2nzjLzPopD17yHB7WBDrQgPeE011dhep40Hg4sE6-ZbqBgc4K4cwfbsXU-ZwTY5b6RiHa8clNtZZW2_Qm1Mbu8jcXs-84OrL9n9t7CgdTBd1lGp8e5j6bAxBJTjwdOWO6Cz492DVAxxNNMyuV0UIJsgEUo8b5IpLD4j2VvOgE_V8FSMuifEsq13OKORjfQ2wApIZDw1QAhXQ9GLx08Nl-0umEcaiXH8f36Pqvt4dRwK6tSIgSMht3qAXNCtBBFQS8fyffu1KyZ8_11gWlQdeisPhKbDGEDBNd2SAN2-lQxrcCBmyJ3oD0PCeS3sV8fvoM4eFRfzYhpg.lI2L7mB4nXr4Lnsk.pkdYMTeQUjmBd5kGUnLL72n4ztIQaotAsy1MQj7180sMkGzNwq9n8mI-1bhpavxgAczRhGfKXSmHfHsF3curt10ClMZOsHOJ8sP93lura_5pU7ZYB0V2stupb6a8IiWWYOdASpjtsKr0VpKRO_AuiaRGC1WZdlhWHnptIP78bkG2P7hV57ht3W-upjIErnRtEY29Vt7ddu-r983l8MLw2-8-jb31LxgJYS2Zkr7eDB-UmI5xygsEHLH_pdqOKqxJhO3U3LkWBlt7a1sH.SzRYiT21_Lv7ae8xxmmfRg
Compact serialization format
JSON Web Encryption (JWE)
Compact serialization format
BASE64URL(UTF8(JWE Protected Header)). BASE64URL(JWE Encrypted Key). BASE64URL(JWE Initialization Vector). BASE64URL(JWE Ciphertext). BASE64URL(JWE Authentication Tag)
{
"protected":"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ",
"encrypted_key":"uWmje_-Y3GF2nzjLzPopD17yHB7WBDrQgPeE011dhep40Hg4sE6-ZbqBgc4K4cwfbsXU-ZwTY5b6RiHa8clNtZZW2_Qm1Mbu8jcXs-84OrL9n9t7CgdTBd1lGp8e5j6bAxBJTjwdOWO6Cz492DVAxxNNMyuV0UIJsgEUo8b5IpLD4j2VvOgE_V8FSMuifEsq13OKORjfQ2wApIZDw1QAhXQ9GLx08Nl-0umEcaiXH8f36Pqvt4dRwK6tSIgSMht3qAXNCtBBFQS8fyffu1KyZ8_11gWlQdeisPhKbDGEDBNd2SAN2-lQxrcCBmyJ3oD0PCeS3sV8fvoM4eFRfzYhpg",
"iv":"lI2L7mB4nXr4Lnsk",
"ciphertext":"pkdYMTeQUjmBd5kGUnLL72n4ztIQaotAsy1MQj7180sMkGzNwq9n8mI-1bhpavxgAczRhGfKXSmHfHsF3curt10ClMZOsHOJ8sP93lura_5pU7ZYB0V2stupb6a8IiWWYOdASpjtsKr0VpKRO_AuiaRGC1WZdlhWHnptIP78bkG2P7hV57ht3W-upjIErnRtEY29Vt7ddu-r983l8MLw2-8-jb31LxgJYS2Zkr7eDB-UmI5xygsEHLH_pdqOKqxJhO3U3LkWBlt7a1sH",
"tag":"SzRYiT21_Lv7ae8xxmmfRg"
}
JSON Web Encryption (JWE)
JSON serialization format
Et le reste...
La gestion
des clés

JSON Web Key
{
"alg":"A128KW",
"kty":"oct",
"k":"GawgguFyGrWKav7AX4VKUg"
}
Exemple de représentation d'une clé symétrique
(c'est la RFC 7517)
JSON Web Key
{
"keys":
[
{
"kty":"oct",
"alg":"A128KW",
"k":"GawgguFyGrWKav7AX4VKUg"
},
{
"kty":"oct",
"k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75
aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow",
"kid":"HMAC key used in JWS spec Appendix A.1 example"
}
]
}
Exemple de représentation d'un set de clés symétriques
{
"alg": "HS256",
"type": "JWT",
"kid": "6d3db68d-5867-458d-921b-1c2426ef78b4"
}
Exemple d'utilisation du kid
JSON Web Key
JSON Web Key
{
"alg": "RS256",
"x5u": "https://key.service.com/key.pem"
}
Exemple d'utilisation de certificat X509
(de la même manière on peut utiliser l'attribut x5c pour embarqué le certificat dans le jeton)
JSON Web Key
{
"alg": "HS256",
"type": "JWT",
"kid": "6d3db68d-5867-458d-921b-1c2426ef78b4",
"jku": "https://key.service.com/keys.json"
}
Exemple d'utilisation JWK set URL
Et le reste...
A quoi
ça sert ?

Jeton d'API
OAuth2

OpenID Connect

Session stateless
Usage "custom"
Et les
attaques ?

Jeton non sécurisé
{
"alg": "none",
"type": "JWT"
}
Entête
RSA public key as shared key
Brute force
Modification des données chiffrées
Substitution
Le paradoxe de JWT
Quelques
conseils
de sécurité


Le secret
Ne pas
tout accepter

Valider
les claims

Préférer l'asymétrique

Utiliser
une librairie
existante et
éprouvée

Ne vous battez pas pour révoquer les JWT

A propos de
confidentialité

Les informations contenues dans un JWS sont lisibles
par tout le monde

Eviter de "logger"
les jetons

Mettre les informations
nécessaires et suffisantes

Quelles
sont les
alternatives?


CleverCloud/biscuit
"authentication and authorization token for microservices architectures"
paragonie/paseto

Platform-Agnostic Security Tokens
rescrv/libmacaroons
"Cookies with Contextual Caveats for Decentralized Authorization in the Cloud"

(image
non officielle...)
tuupola/branca
"Authenticated and encrypted API tokens using modern crypto."

(pas plus
officielle...)
Il est temps
de conclure !

Pour résumer

Merci à tous pour votre attention !
Karim PINCHON - @kpn13
https://slides.com/kpn13

Connaissez-vous vraiment JWT ? - Confoo 2023
By Karim PINCHON
Connaissez-vous vraiment JWT ? - Confoo 2023
- 585