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,191