Connaissez-vous vraiment JWT ?

A propos
De
Moi

  • Karim Pinchon
  • Développeur depuis ~10 ans
  • Actuellement chez
  • @kpn13

Je ne suis pas un cryptographe

Avant
De
Débuter...

C'est quoi un jeton ?

  • chaine de caractères
  • authentification
  • autorisation
  • ...

(On a le droit de dire token aussi)

ça a quelle forme ?

ça sert à quoi ?

Une simple chaine ?

Référence

Valeur

JSON Web Token

"Jot"

(Mais j'crois pas que beaucoup de dev prononcent comme ça)

https://jwt.io/

Un
Petit
Apparté...

https://chiffrer.info/

@OnDitChiffrer

Crypter ou chiffrer ?

Signer

  • intégrité
  • authentification
  • non répudiation

Chiffrer

  • confidentialité

A
Quoi ça
Ressemble?

JWT.IO

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": "AFUPDay Lille/Rennes 2021",
  "exp": 1622246399,
  "jti": "7a365dd0-7bc7-4894-bb09-771ea152cc55"
}

HMACSHA256(
  base64UrlEncode(      ) + "." +
  base64UrlEncode(payload),
  UN_SECRET)

entête

charge utile

.

.

header

{
  "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
Maintenant
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.0

OpenID Connect

Session stateless

Usage "custom"

Et
Les
Attaques ?

Jeton non sécurisé

{
    "alg": "none",
    "type": "JWT"
}

Entête

Brute force

RSA ou HMAC ?

Mauvais développeurs ?

Le paradoxe de JWT

Quelques
Conseils
De sécurité

Le secret

Ne pas tout accepter

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 2021 on n'a plus

besoin de le dire hein ?)

Quelles
Sont les
Alternatives?

A-t-on besoin

d'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

Remerciements

Merci à tous pour votre attention !

Karim PINCHON - @kpn13