Aller au contenu

JWS : signer et sécuriser vos échanges JSON avec JSON Web Signature

Ce contenu est une ébauche et ne sera pas inclus dans la version de production.

JWS : signer et sécuriser vos échanges JSON avec JSON Web Signature

Section intitulée « JWS : signer et sécuriser vos échanges JSON avec JSON Web Signature »

JSON Web Signature (JWS) est une norme ouverte définie dans la RFC (Request for Comments) 7515 qui permet de signer numériquement des données structurées au format JSON (JavaScript Object Notation). Cette signature garantit l’intégrité et l’authenticité des données échangées entre systèmes, sans en chiffrer le contenu. JWS est largement utilisé dans les protocoles d’authentification et d’autorisation modernes, notamment OAuth 2.0 (Open Authorization) et OpenID Connect.

Ce document technique présente les concepts fondamentaux de JSON Web Signature (JWS), son contexte d’utilisation, sa structure, ainsi qu’un exemple concret d’implémentation. Il s’adresse aux développeurs, architectes et ingénieurs sécurité qui souhaitent intégrer JWS dans leurs systèmes pour assurer la confiance dans les échanges de données.

Le public visé comprend les professionnels de l’informatique et de la sécurité qui manipulent des échanges de données sensibles ou critiques. Le besoin principal est de garantir que les données reçues n’ont pas été altérées et proviennent bien d’une source authentifiée. JSON Web Signature (JWS) répond à ce besoin en fournissant un mécanisme standardisé de signature numérique pour des objets JSON.

Le cas d’usage typique est la sécurisation des tokens d’authentification ou d’autorisation, où un serveur émetteur signe un jeton JSON, et un serveur récepteur vérifie cette signature avant d’accorder l’accès à une ressource. JSON Web Signature (JWS) est aussi utilisé pour signer des messages dans des architectures distribuées, garantissant ainsi la non-répudiation et l’intégrité.

JSON Web Signature (JWS) repose sur une structure composée de trois parties encodées en Base64URL (Base64 URL-safe) et séparées par des points (.) :

  1. Header (en-tête) : décrit l’algorithme de signature utilisé (ex. RS256, ES256) et d’autres paramètres optionnels.
  2. Payload (charge utile) : contient les données JSON à protéger, par exemple des revendications (claims) dans un token.
  3. Signature : résultat de la signature cryptographique du header et du payload concaténés.

Le format compact JSON Web Signature (JWS) est la représentation la plus courante, sous la forme :

Base64URL(header) . Base64URL(payload) . Base64URL(signature)

Cette structure facilite le transport dans des environnements HTTP, notamment dans des en-têtes d’autorisation.

JSON Web Signature (JWS) supporte plusieurs algorithmes cryptographiques, notamment :

  • RS256 : RSA (Rivest-Shamir-Adleman) avec SHA-256 (Secure Hash Algorithm 256 bits), basé sur une clé privée RSA pour signer et une clé publique pour vérifier.
  • ES256 : ECDSA (Elliptic Curve Digital Signature Algorithm) avec la courbe P-256.
  • HS256 : HMAC (Hash-based Message Authentication Code) avec SHA-256, utilisant une clé secrète partagée.

Le choix de l’algorithme dépend du contexte de sécurité et des contraintes d’infrastructure.

Pour vérifier une signature JSON Web Signature (JWS), le récepteur doit :

  • Décoder le header et le payload.
  • Reconstituer la chaîne à signer : Base64URL(header) . Base64URL(payload).
  • Appliquer l’algorithme de vérification avec la clé publique ou la clé secrète.
  • Comparer la signature calculée avec celle reçue.

Cette validation assure que le contenu n’a pas été modifié et que la signature provient bien du détenteur de la clé privée.

Supposons un serveur d’authentification qui émet un token JSON Web Signature (JWS) signé avec RS256 pour un utilisateur authentifié.

  1. Header JSON :

    {
    "alg": "RS256",
    "typ": "JWT"
    }
  2. Payload JSON (claims utilisateur) :

    {
    "sub": "1234567890",
    "name": "Alice Dupont",
    "iat": 1686400000
    }
  3. Encodage Base64URL des deux parties :

    • Header encodé : eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
    • Payload encodé : eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIER1cG9udCIsImlhdCI6MTY4NjQwMDAwMH0
  4. Signature : le serveur signe la chaîne concaténée header.payload avec sa clé privée RSA en SHA-256.

  5. JWS final :

    eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIER1cG9udCIsImlhdCI6MTY4NjQwMDAwMH0.[signature]

Exemple d’appel PKCS#11 (Public-Key Cryptography Standards #11) pour générer une clé RSA et signer un JWS

Section intitulée « Exemple d’appel PKCS#11 (Public-Key Cryptography Standards #11) pour générer une clé RSA et signer un JWS »

Voici un exemple commenté en C utilisant l’API PKCS#11 (Public-Key Cryptography Standards #11) pour générer une clé RSA et signer un message, étape clé dans la création d’un JSON Web Signature (JWS) avec RS256 :

// Initialisation de la session PKCS#11 et ouverture
CK_SESSION_HANDLE hSession;
CK_SLOT_ID slotID = 0; // ID du slot HSM (Hardware Security Module)
CK_RV rv = C_OpenSession(slotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &hSession);
// Authentification utilisateur
rv = C_Login(hSession, CKU_USER, userPin, userPinLen);
// Génération d’une paire de clés RSA 2048 bits
CK_MECHANISM mechanism = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
CK_OBJECT_HANDLE hPublicKey, hPrivateKey;
CK_ATTRIBUTE publicKeyTemplate[] = {
{CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
{CKA_PUBLIC_EXPONENT, publicExponent, sizeof(publicExponent)},
{CKA_VERIFY, &trueValue, sizeof(trueValue)}
};
CK_ATTRIBUTE privateKeyTemplate[] = {
{CKA_SIGN, &trueValue, sizeof(trueValue)},
{CKA_SENSITIVE, &trueValue, sizeof(trueValue)},
{CKA_EXTRACTABLE, &falseValue, sizeof(falseValue)}
};
rv = C_GenerateKeyPair(hSession, &mechanism,
publicKeyTemplate, sizeof(publicKeyTemplate)/sizeof(CK_ATTRIBUTE),
privateKeyTemplate, sizeof(privateKeyTemplate)/sizeof(CK_ATTRIBUTE),
&hPublicKey, &hPrivateKey);
// Préparation des données à signer (header.payload encodé en Base64URL)
unsigned char dataToSign[] = "..."; // chaîne à signer
unsigned long dataLen = ...;
// Signature avec RSASSA-PKCS1-v1_5 SHA-256
CK_MECHANISM signMech = {CKM_SHA256_RSA_PKCS, NULL_PTR, 0};
rv = C_SignInit(hSession, &signMech, hPrivateKey);
unsigned char signature[256];
unsigned long sigLen = sizeof(signature);
rv = C_Sign(hSession, dataToSign, dataLen, signature, &sigLen);
// La signature peut ensuite être encodée en Base64URL et concaténée pour former le JWS
// Fermeture de session et déconnexion
C_Logout(hSession);
C_CloseSession(hSession);

Le client ou le service consommateur récupère la clé publique RSA correspondante, décode les deux premières parties, puis vérifie la signature. Si la vérification réussit, le payload est considéré authentique et intègre.

  • La clé privée doit être protégée avec rigueur pour éviter toute compromission.
  • Le choix de l’algorithme doit correspondre aux exigences de sécurité et de performance.
  • La gestion des horodatages (iat - issued at, exp - expiration) dans le payload est essentielle pour limiter la validité du token.
  • La validation doit inclure la vérification des paramètres du header pour éviter les attaques par substitution d’algorithme.

JSON Web Signature (JWS) est une norme permettant de signer numériquement des objets JSON (JavaScript Object Notation) pour garantir leur intégrité et authenticité, sans chiffrer leur contenu.

Quelle différence entre JWS et JSON Web Token (JWT) ?

Section intitulée « Quelle différence entre JWS et JSON Web Token (JWT) ? »

JSON Web Token (JWT) est un format de token qui utilise souvent JSON Web Signature (JWS) pour signer ses données. JWS est la méthode de signature, tandis que JWT est un format d’objet JSON structuré souvent signé avec JWS.

Quels algorithmes de signature sont recommandés pour JWS ?

Section intitulée « Quels algorithmes de signature sont recommandés pour JWS ? »

Les algorithmes asymétriques comme RS256 (RSA avec SHA-256) ou ES256 (ECDSA avec P-256) sont recommandés pour une meilleure sécurité. HS256 (HMAC avec SHA-256) est utilisé dans des contextes où une clé secrète partagée est possible.

Comment protéger la clé privée utilisée pour signer un JWS ?

Section intitulée « Comment protéger la clé privée utilisée pour signer un JWS ? »

La clé privée doit être stockée dans un module matériel sécurisé (HSM (Hardware Security Module)) ou un coffre-fort logiciel avec contrôle d’accès strict. Elle ne doit jamais être exposée dans des environnements non sécurisés.

Non, JSON Web Signature (JWS) ne chiffre pas les données. Pour chiffrer, il faut utiliser JSON Web Encryption (JWE). JWS garantit uniquement la signature et l’intégrité.

JSON Web Signature (JWS) est un composant clé pour sécuriser les échanges de données JSON en garantissant leur intégrité et authenticité via une signature numérique. Sa structure simple, combinée à des algorithmes cryptographiques robustes, en fait un standard incontournable dans les systèmes modernes d’authentification et d’autorisation.

La compréhension précise de sa structure, des algorithmes supportés et des bonnes pratiques de gestion des clés est essentielle pour une implémentation sécurisée. L’exemple concret présenté illustre comment créer et valider un JSON Web Signature (JWS) dans un contexte d’authentification, démontrant ainsi son utilité pratique.

Intégrer JSON Web Signature (JWS) dans vos architectures permet d’assurer la confiance dans les échanges JSON, condition indispensable à la sécurité des applications distribuées.