Connaissez-vous vraiment JWT ?
A propos
de moi
- Karim Pinchon
- Développeur back (~10 ans)
- Actuellement chez Ornikar
- @kpn13
Je ne suis pas un cryptographe
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"
Votez
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
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
Évidemment transiter via HTTPS
uniquement mais en 2022 on n'a plus
besoin de le dire hein ?
Quelles
sont les
alternatives?
par
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) Pierre Tibulle @ptibulle
Remerciements
Merci à tous pour votre attention !
Karim PINCHON - @kpn13
Connaissez-vous vraiment JWT ? - Devoxx France 2022
By Karim PINCHON
Connaissez-vous vraiment JWT ? - Devoxx France 2022
- 1,075