Premiers pas avec jwt

JWT non signé

Un JWT non signé a la valeur d’en-tête “alg : none” et un composant JWS (signature) vide :

eyJhbGciOiJub25lIn0
.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ
.

Le point de fin indique que la signature est vide.

Entête

{
  "alg": "none"
}

Charge utile

{
  "iss": "joe",
  "exp": 1300819380,
  "http://example.com/is_root": true
}

JWT signé (JWS)

Un JWT signé inclut une signature encodée Base64 Url Safe comme troisième composant. L’algorithme utilisé pour générer la signature est indiqué dans l’en-tête.

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
.eyJzdWIiOiJKb2huIERvZSIsImFkbWluIjp0cnVlLCJpYXQiOjE0NzAzNTM5OTQsImV4cCI6MTQ3MDM1NzYyNywianRpIjoiNmU0MDRiYTgtZjg4NS00ZDVmLWJmYTItZTNmNWEwODM4MGE0In0
.7CfBdVP4uKsb0cogYepCvMLm8rcpjBYW1XZzA-a5e44

Entête

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

Ce JWT a été signé avec l’algorithme HMAC-SHA256, d’où alg: HS256.

Charge utile

{
  "sub": "John Doe",
  "admin": true,
  "iat": 1470353994,
  "exp": 1470357627,
  "jti": "6e404ba8-f885-4d5f-bfa2-e3f5a08380a4"
}

Ce JWT peut être vérifié avec le secret UTF-8 “notsosecret”.

Comment savoir si vous avez un JWS ou un JWE ?

À partir de la section 9 de la spécification JSON Web Encryption (RFC 7516) :

L’en-tête JOSE pour un JWS peut être distingué de l’en-tête JOSE pour un JWE en examinant la valeur du paramètre d’en-tête “alg” (algorithme). Si la valeur représente une signature numérique ou un algorithme MAC, ou est la valeur “aucun”, c’est pour un JWS ; s’il représente un algorithme de chiffrement de clé, d’encapsulation de clé, d’accord de clé direct, d’accord de clé avec encapsulage de clé ou de chiffrement direct, il s’agit d’un JWE. (L’extraction de la valeur “alg” à examiner est simple lors de l’utilisation de la sérialisation JWS Compact ou de la sérialisation JWE Compact et peut être plus difficile lors de l’utilisation de la sérialisation JWS JSON ou de la sérialisation JWE JSON.)

Et

L’en-tête JOSE pour un JWS peut également être distingué de l’en-tête JOSE pour un JWE en déterminant si un membre “enc” (algorithme de chiffrement) existe. Si le membre “enc” existe, il s’agit d’un JWE ; sinon, c’est un JWS.

JWS (signé)##

{
  "alg": "HS256"
}

PLAY (crypté)

{
  "alg":"RSA1_5",
  "enc":"A256GCM",
  "iv":"__79_Pv6-fg",
  "x5t":"7noOPq-hJ1_hCnvWh6IeYI2w9Q0"
}

Chiffrement Web JSON (PLAY)

JSON Web Encryption (JWE) représente le contenu chiffré à l’aide de structures de données basées sur JavaScript Object Notation (JSON). Il définit un moyen de crypter vos données de réclamation afin que seul le destinataire prévu puisse lire les informations présentes dans un jeton.

Dans la sérialisation JWE JSON, un JWE est représenté comme un objet JSON contenant tout ou partie de ces huit membres :

  "protected", with the value BASE64URL(UTF8(JWE Protected Header))
  "unprotected", with the value JWE Shared Unprotected Header
  "header", with the value JWE Per-Recipient Unprotected Header
  "encrypted_key", with the value BASE64URL(JWE Encrypted Key)
  "iv", with the value BASE64URL(JWE Initialization Vector)
  "ciphertext", with the value BASE64URL(JWE Ciphertext)
  "tag", with the value BASE64URL(JWE Authentication Tag)
  "aad", with the value BASE64URL(JWE AAD)

Les six chaînes de résultat encodées en base64url et les deux JSON non protégés les valeurs d’objet sont représentées en tant que membres dans un objet JSON.

Exemple de JEU

L’exemple d’en-tête JWE suivant déclare que :

  • la clé de chiffrement de contenu est chiffrée au destinataire à l’aide de l’algorithme RSA-PKCS1_1.5 pour produire la clé chiffrée JWE

  • le texte en clair est crypté à l’aide de l’algorithme AES-256-GCM pour produire le texte chiffré JWE

  • le vecteur d’initialisation 64 bits spécifié avec l’encodage base64url __79_Pv6-fg a été utilisé

  • l’empreinte du certificat X.509 qui correspond à la clé utilisée pour chiffrer le JWE a l’encodage base64url 7noOPq-hJ1_hCnvWh6IeYI2w9Q0.

    { “alg”:“RSA1_5”, “enc”:“A256GCM”, “iv”:"__79_Pv6-fg", “x5t”:“7noOPq-hJ1_hCnvWh6IeYI2w9Q0” }

Base64url encodant les octets de la représentation UTF-8 de l’en-tête JWE donne cette valeur d’en-tête JWE codé (avec des sauts de ligne à des fins d’affichage uniquement) :

eyJhbGciOiJSU0ExXzUiLA0KICJlbmMiOiJBMjU2R0NNIiwNCiAiaXYiOiJfXzc5
X1B2Ni1mZyIsDQogIng1dCI6Ijdub09QcS1oSjFfaENudldoNkllWUkydzlRMCJ

Lisez [spécification JSON Web Encryption (RFC 7516)][1] pour plus d’informations

[1] : https://tools.ietf.org/html/rfc7516

Que stocker dans un JWT

Le JWT [RFC][1] établit trois classes de revendications :

  • Revendications enregistrées comme sub, iss, exp ou nbf

Revendications publiques avec des noms publics ou des noms [enregistrés par l’IANA][2] qui contiennent des valeurs qui doivent être uniques comme email, address ou phone_number. Voir [liste complète][3]

  • Revendications privées à utiliser dans votre propre contexte et les valeurs peuvent entrer en collision

Aucune de ces revendications n’est obligatoire

Un JWT est autonome et doit éviter d’utiliser la session serveur fournissant les données nécessaires pour effectuer l’authentification (pas besoin de stockage sur le serveur et d’accès à la base de données). Par conséquent, les informations de “rôle” ou de “permissions” peuvent être incluses dans les revendications privées de JWT.

Réclamations enregistrées

Les noms de réclamation suivants sont enregistrés dans le registre IANA “JSON Web Token Claims” établi par [Section 10.1.][2]

  • iss (émetteur) : identifie le mandant qui a émis le JWT.
  • sub (subject): identifie le principal qui est le sujet du JWT. Doit être unique
  • aud (audience) : identifie les destinataires auxquels le JWT est destiné (tableau de chaînes/uri)
  • exp (expiration time) : identifie l’heure d’expiration (UTC Unix) après laquelle vous ne devez plus accepter ce jeton. Cela devrait être après l’heure d’émission.
  • nbf(not before) : identifie l’heure UTC Unix avant laquelle le JWT ne doit pas être accepté
  • iat (émis à) : identifie l’heure UTC Unix à laquelle le JWT a été émis
  • jti (JWT ID) : fournit un identifiant unique pour le JWT.

Exemple

{
    "iss": "stackoverflow",
    "sub": "joe",
    "aud": ["all"],
    "iat": 1300819370,
    "exp": 1300819380,
    "jti": "3F2504E0-4F89-11D3-9A0C-0305E82C3301"
    "context": {
        "user": {
            "key": "joe",
            "displayName": "Joe Smith"
        },
        "roles":["admin","finaluser"]
    }
}

[1] : https://tools.ietf.org/html/rfc7519#page-8 [2] : https://tools.ietf.org/html/rfc7519#section-10.1 [3] : http://www.iana.org/assignments/jwt/jwt.xhtml