JWT (JSON Web Token) zazwyczaj składa się z nagłówka + ładunku + podpisu.
Nagłówek
Zawiera informacje o metadanych dotyczące JWT.
alg: algorytm użyty do podpisania tokenu.
typ: typ tokenu, zawsze JWT.
{
"alg": "HS256",
"typ": "JWT"
}
Można znaleźć więcej nagłówków, jednak poprzednie będą zawsze obecne.
Ładunek
Ładunek zawiera roszczenia JWT. Standardowe nagłówki są następujące:
iss: wystawca, podmiot generujący i wystawiający JWT.
sub: podmiot, encja identyfikowana przez ten token.
aud: odbiorca, docelowa grupa odbiorców tego JWT.
exp: czas wygaśnięcia — znacznik czasu w formacie UNIX, po którym token nie powinien być akceptowany.
iat: issued at — określa datę wystawienia tokenu.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Podpis
Podpis jest tworzony przy użyciu zakodowanego nagłówka, zakodowanego ładunku, sekretu i algorytmu kryptograficznego.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Następujące algorytmy są obsługiwane zarówno przez składniki JWT klienta, jak i serwera.
Wymagane są biblioteki OpenSSL do podpisywania i weryfikacji JWT, z jednym wyjątkiem.
Trzy algorytmy ML-DSA to postkwantowe algorytmy JOSE z RFC 9964 i to one są wspomnianym wyżej wyjątkiem: zostały zaimplementowane w czystym Object Pascal w pakiecie sgcCrypto, więc podpisują i weryfikują bez obecności jakiejkolwiek biblioteki OpenSSL. Podpisem jest ML-DSA według FIPS 204 w trybie czystym (pure) z pustym kontekstem, liczony nad danymi wejściowymi podpisu JWS i przenoszony w tokenie jako base64url. Podpisywanie jest deterministyczne, więc ten sam klucz i te same dane wejściowe zawsze dają ten sam podpis.
Wartości wyliczeniowe to jwtMLDSA44, jwtMLDSA65 i jwtMLDSA87, a nagłówek alg, który zapisują, to ML-DSA-44, ML-DSA-65 i ML-DSA-87. Klient podpisuje kluczem JWTOptions.Algorithms.MLDSA.PrivateKey, czyli kluczem prywatnym PKCS#8 w formacie PEM, a serwer weryfikuje kluczem JWTOptions.Algorithms.MLDSA.PublicKey, czyli kluczem publicznym SubjectPublicKeyInfo w formacie PEM. Zestaw parametrów klucza musi być tym, który nazywa algorytm: w przeciwnym razie podpisywanie zgłasza wyjątek, a weryfikacja zwraca False.
Podpisy są duże. Podpis ML-DSA-44 ma 2420 bajtów wobec 64 bajtów dla ES256, więc token rośnie o mniej więcej 3,2 KB danych base64url, a podpis ML-DSA-87 o około 6,2 KB. Przed wdrożeniem sprawdź limity rozmiaru nagłówków we wszystkim, przez co ten token przechodzi.
Klucze można również przenosić jako klucze JSON Web Key typu AKP, RFC 9964 sekcje 3 i 4. sgcMLDSA_ExportPublicJWK i sgcMLDSA_ExportPrivateJWK zapisują taki klucz, sgcMLDSA_ImportJWK odczytuje obie postacie, a sgcMLDSA_ImportJWKAsPEM przekształca JWK wprost w łańcuchy PEM, które odczytują oba komponenty. Prywatny JWK przechowuje 32-bajtowe ziarno w polu priv, jedynej postaci prywatnej zdefiniowanej w sekcji 4, więc rozwiniętego klucza prywatnego nie da się zapisać jako JWK. Wszystkie cztery funkcje są zadeklarowane w sgcHTTP_JWT_MLDSA.
* Algorytmy ML-DSA wymagają pakietu sgcCrypto. Bez niego wartości wyliczeniowe nadal istnieją, więc formularz zapisany z jedną z nich nadal się wczytuje, ale podpisywanie zgłasza wyjątek, a każdy token ML-DSA jest odrzucany.
TsgcHTTP_JWT_Client: Klient JWT umożliwiający kodowanie i podpisywanie JWT oraz wysyłanie go jako nagłówka Authorization w protokołach HTTP i WebSocket.
TsgcHTTP_JWT_Server: Serwer JWT umożliwiający dekodowanie i walidację JWT odbieranych jako nagłówek autoryzacji w protokołach HTTP i WebSocket.
* Składniki JWT wymagają co najmniej wersji Indy 10.6.0.5169 lub sgcWebSockets Enterprise Edition.