Les cinq exemples ci-dessous produisent le même résultat, avec la même clé de test et la même charge utile, pour vous permettre de comparer.
- Clé de test :
YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE. À ne jamais utiliser en production. - Identifiant de clé :
ab12cd34. - Charge utile :
{"first-name": "Marie", "id_adherent": "70123456"}.
Chaque exécution produit un paramètre différent, le mode GCM tirant un vecteur d’initialisation aléatoire à chaque chiffrement. Tous produisent un paramètre que le serveur déchiffre en retrouvant la charge utile d’origine.
Le décodage de la clé est la première étape de chaque exemple. La clé affichée dans le back-office est un encodage : elle fait 43 caractères en base64url, mais représente 32 octets. Si vous la transmettez telle quelle à votre bibliothèque, celle-ci reçoit une clé de la mauvaise longueur et renvoie une erreur qui ne désigne pas la vraie cause.
Node.js #
Bibliothèque : jose. Installation : npm i jose.
import { CompactEncrypt, base64url } from 'jose';
const rawKey = base64url.decode('YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE');
const claims = { 'first-name': 'Marie', id_adherent: '70123456' };
const token = await new CompactEncrypt(new TextEncoder().encode(JSON.stringify(claims)))
.setProtectedHeader({ alg: 'dir', enc: 'A256GCM', kid: 'ab12cd34' })
.encrypt(rawKey);
Java #
Bibliothèque : Nimbus JOSE + JWT. Dépendance Maven : com.nimbusds:nimbus-jose-jwt.
import com.nimbusds.jose.EncryptionMethod;
import com.nimbusds.jose.JWEAlgorithm;
import com.nimbusds.jose.JWEHeader;
import com.nimbusds.jose.JWEObject;
import com.nimbusds.jose.Payload;
import com.nimbusds.jose.crypto.DirectEncrypter;
import java.util.Base64;
byte[] rawKey = Base64.getUrlDecoder().decode("YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE");
String payload = "{\"first-name\":\"Marie\",\"id_adherent\":\"70123456\"}";
JWEHeader header = new JWEHeader.Builder(JWEAlgorithm.DIR, EncryptionMethod.A256GCM)
.keyID("ab12cd34")
.build();
JWEObject jwe = new JWEObject(header, new Payload(payload));
jwe.encrypt(new DirectEncrypter(rawKey));
String token = jwe.serialize();
.NET #
Bibliothèque : jose-jwt. Paquet NuGet : jose-jwt.
using System.Collections.Generic;
byte[] rawKey = Jose.Base64Url.Decode("YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE");
var claims = new Dictionary<string, object>
{
{ "first-name", "Marie" },
{ "id_adherent", "70123456" },
};
var extraHeaders = new Dictionary<string, object> { { "kid", "ab12cd34" } };
string token = Jose.JWT.Encode(claims, rawKey, Jose.JweAlgorithm.DIR, Jose.JweEncryption.A256GCM, extraHeaders: extraHeaders);
Python #
Bibliothèque : python-jose. Installation : pip install "python-jose[cryptography]".
Le rembourrage est ajouté avant le décodage, la chaîne base64url publiée n’en comportant pas.
import base64
import json
from jose import jwe
base64_url_key = "YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE"
padding = "=" * (-len(base64_url_key) % 4)
raw_key = base64.urlsafe_b64decode(base64_url_key + padding)
assert len(raw_key) == 32
claims = {"first-name": "Marie", "id_adherent": "70123456"}
token = jwe.encrypt(
json.dumps(claims).encode("utf-8"),
raw_key,
algorithm="dir",
encryption="A256GCM",
kid="ab12cd34",
)
PHP #
Bibliothèque : web-token/jwt-library. Installation : composer require web-token/jwt-library.
Le membre k de la clé JWK attend la chaîne base64url telle quelle, c’est une propriété du format JWK. Le décodage sert ici à vérifier la longueur avant usage.
<?php
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\JWK;
use Jose\Component\Encryption\Algorithm\ContentEncryption\A256GCM;
use Jose\Component\Encryption\Algorithm\KeyEncryption\Dir;
use Jose\Component\Encryption\JWEBuilder;
use Jose\Component\Encryption\Serializer\CompactSerializer;
$base64UrlKey = 'YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE';
$rawKey = base64_decode(strtr($base64UrlKey, '-_', '+/'), true);
if (32 !== \strlen($rawKey)) {
throw new \RuntimeException('The key must be exactly 32 bytes once decoded.');
}
$claims = ['first-name' => 'Marie', 'id_adherent' => '70123456'];
$algorithmManager = new AlgorithmManager([new Dir(), new A256GCM()]);
$jwk = new JWK(['kty' => 'oct', 'k' => $base64UrlKey]);
$jwe = (new JWEBuilder($algorithmManager))
->create()
->withPayload(json_encode($claims, \JSON_THROW_ON_ERROR))
->withSharedProtectedHeader(['alg' => 'dir', 'enc' => 'A256GCM', 'kid' => 'ab12cd34'])
->addRecipient($jwk)
->build();
$token = (new CompactSerializer())->serialize($jwe, 0);
