JWT (JSON Web Token) typically consists of a header + payload + signature.
Header
Contains the metadata information about the JWT.
alg: the algorithm used to sign the token.
typ: the type of the token, always JWT.
{
"alg": "HS256",
"typ": "JWT"
}
You can find more headers, but the previous ones will always be present.
Payload
The payload contains the claims of the JWT. The standard headers are the following:
iss: the issuer, the entity that generates and issues the JWT.
sub: the subject, the entity identified by this token.
aud: the audience, the target audience for this JWT.
exp: the expiry, the timestamp in UNIX format after which the token should not be accepted.
iat: issued at, specifies the date when the token was issued.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Signature
The signature is created using the Encoded Header, Encoded Payload, a Secret and a Cryptographic Algorithm.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
The following algorithms are supported by both Client and Server JWT components.
OpenSSL libraries are required to sign and verify the JWT, with one exception.
The three ML-DSA algorithms are the post-quantum JOSE algorithms of RFC 9964, and they are the exception above: they are implemented in pure Object Pascal in the sgcCrypto pack, so they sign and validate with no OpenSSL library present. The signature is FIPS 204 ML-DSA in the pure mode with an empty context over the JWS signing input, carried in the token as base64url. The signer is deterministic, so the same key and the same input always produce the same signature.
The enum values are jwtMLDSA44, jwtMLDSA65 and jwtMLDSA87, and the alg header they write is ML-DSA-44, ML-DSA-65 and ML-DSA-87. The client signs with JWTOptions.Algorithms.MLDSA.PrivateKey, a PKCS#8 PEM private key, and the server validates with JWTOptions.Algorithms.MLDSA.PublicKey, a SubjectPublicKeyInfo PEM public key. The parameter set of the key has to be the one the algorithm names: signing raises otherwise, and validating returns False.
Signatures are large. An ML-DSA-44 signature is 2420 bytes against 64 for ES256, so a token grows by roughly 3.2 KB of base64url, and an ML-DSA-87 one by about 6.2 KB. Check the header size limits of anything the token passes through before adopting it.
Keys can also be carried as AKP JSON Web Keys, RFC 9964 sections 3 and 4. sgcMLDSA_ExportPublicJWK and sgcMLDSA_ExportPrivateJWK write one, sgcMLDSA_ImportJWK reads either form, and sgcMLDSA_ImportJWKAsPEM converts a JWK straight into the PEM strings the two components read. A private JWK stores the 32-byte seed in priv, the only private form section 4 defines, so an expanded private key cannot be written as a JWK. All four functions are declared in sgcHTTP_JWT_MLDSA.
* The ML-DSA algorithms need the sgcCrypto pack. Without it the enum values still exist, so a form stored with one still loads, but signing raises and every ML-DSA token is rejected.
TsgcHTTP_JWT_Client: JWT client which allows you to encode and sign JWT and send as an Authorization Header in HTTP and WebSocket protocols.
TsgcHTTP_JWT_Server: JWT server which allows you to decode and validate JWT received as an Authorization Header in HTTP and WebSocket protocols.
* JWT Components require at least Indy version 10.6.0.5169 or sgcWebSockets Enterprise Edition.