INTRODUCTION
In Lesson 4.1, we secured the transport pipe (mTLS). However, data traversing that pipe is exposed in cleartext inside the TLS tunnel. While this is secure for transit, two vulnerabilities remain:
-
Authorization Server Relays: If the TLS session terminates at the ASPSP’s API gateway, and the request is forwarded internally via HTTP (without mTLS), the JWT payload is exposed to internal network sniffers.
-
Long-Term Audits: The ASPSP must store the JWT assertions and consent records for 5–7 years. If stored as plaintext, a future breach of the audit database would expose all historical PSU data.
The Solution: Payload-level cryptography using the JOSE (JSON Object Signing and Encryption) stack. This includes:
-
JWT (JSON Web Token) : The compact container format.
-
JWS (JSON Web Signature) : Provides integrity and non-repudiation via digital signatures (PS256). The payload is signed, but still readable (base64 encoded).
-
JWE (JSON Web Encryption) : Provides confidentiality. The payload is encrypted (AES-GCM) and the symmetric key is wrapped with the recipient’s RSA public key (RSA-OAEP).
In this lesson, we mathematically analyze the JWS signature verification (RSA-PSS vs. ECDSA) and the JWE encryption overhead (symmetric AES-GCM vs. asymmetric key wrapping). We derive the exact byte size inflation (JWE adds ~250 bytes overhead) and calculate the CPU cost (JWS verification takes 0.5ms, JWE encryption takes 0.8ms). We will also formalize the key rotation policy for the signing keys (JWKS), using the formula T_rotate = min(24h, T_compromise_risk) to ensure that a key compromise affects only a limited time window.
LEARNING OBJECTIVES
-
Deconstruct the JWT Compact Serialization—deriving the exact Base64URL encoding formula:
JWT = Header.Base64Url || '.' || Payload.Base64Url || '.' || Signature.Base64Url, and calculating the byte-size overhead relative to the raw JSON. -
Analyze JWS Signatures (PS256 vs. ES256)—comparing the deterministic probabilistic padding of RSA-PSS (PS256) with the Elliptic Curve signature (ES256) used in some jurisdictions, and proving mathematically that ES256 verification is 4x faster than PS256, while PS256 is quantum-resistant.
-
Formalize JWE Encryption—defining the 5-step encryption process: (1) Generate a Content Encryption Key (CEK), (2) Encrypt the payload with AES-GCM, (3) Encrypt the CEK with RSA-OAEP, (4) Serialize the JWE compact format, and (5) Decrypt on the recipient’s side using their private key.
-
Quantify the Cryptographic Overhead—measuring the latency of JWS verification (0.5ms), JWE encryption (0.8ms), and JWE decryption (1.2ms), and proving that this overhead is acceptable for the 850ms UK p95 SLA.
-
Design the JWKS Rotation Schedule—deriving the optimal rotation frequency using the formula
T_rotation = min(24h, 2 × T_compromise_detection), ensuring that a stolen private key has a short window of usability. -
Compare JWE vs. JWS for Different Use Cases—mapping the specific Open Banking artifacts to the appropriate protection mechanism: ID Tokens and Access Tokens are signed only (JWS) because they are short-lived and transmitted over mTLS; Consent payloads and sensitive PII in audit logs should be encrypted (JWE) for long-term confidentiality.
PART 1: THE JWT COMPACT SERIALIZATION — The 3-Part Architecture
A JWT is a compact, URL-safe token consisting of three parts:
-
Header: Contains the algorithm (e.g.,
PS256) and the key ID (kid). -
Payload: Contains the claims (e.g.,
iss,sub,aud,exp,scope,consent_id). -
Signature: The cryptographic signature (or encryption).
Byte-size Calculation:
-
Raw JSON (250 bytes) + Base64URL overhead (33% expansion) ≈ 333 bytes.
-
Signature (PS256, 256 bytes) + Base64URL ≈ 344 bytes.
-
Total JWT Size: ~700 bytes.
This is extremely compact, allowing the token to be transmitted in a single TCP packet (MTU 1500 bytes) for most networks.
PART 2: JWS — Digital Signatures for Integrity and Non-Repudiation
2.1 The Signing Algorithms (PS256 vs. ES256)
The FAPI 1.0 Advanced profile requires signatures for:
-
Client Assertion JWT.
-
ID Token.
-
JARM Authorization Response.
Two algorithms are permitted:
-
PS256 (RSA-PSS) : Uses the RSA-PSS probabilistic signature scheme. The signature is generated by hashing the payload with SHA-256, applying the RSA-PSS padding (which includes a random salt), and exponentiating with the private key.
-
ES256 (ECDSA) : Uses Elliptic Curve Digital Signature Algorithm with the P-256 curve. It is significantly faster (verification is ~0.1ms vs 0.5ms for PS256) and uses smaller keys (256 bits vs 2048 bits).
Why PS256 is Preferred: The UK OBIE and Brazil’s BCB mandate PS256 because RSA-based signatures are considered “quantum-resistant” in the near term (Shor’s algorithm breaks ECDSA more easily than RSA-PSS for equivalent key sizes). However, the latency difference (0.4ms) is negligible for open banking flows.
The Verification Math:
For PS256, verification computes s^e mod n and checks it against the expected hash. For ES256, verification checks that the elliptic curve point generated by the signature lies on the curve and satisfies the verification equation u1 × G + u2 × Q = R. The ECDSA verification is algebraically simpler, hence faster.
2.2 The kid (Key ID) and JWKS Rotation
The JWT header includes the kid claim, which references the specific signing key in the ASPSP’s JWKS. When the TPP verifies the JWT signature, it fetches the JWKS (cached for 12 hours) and selects the key with the matching kid.
Key Rotation Schedule:
We define the minimum rotation interval T_rotation = 24 hours (per UK OBIE recommendation). The ASPSP generates a new key pair, publishes it in the JWKS, and waits for a grace period (4 hours) before deactivating the old key to allow TPPs to update their cache.
Mathematical Definition:T_overlap = max(JWKS_Cache_TTL, 4h).
If the cache TTL is 12 hours, we set the overlap to 16 hours to guarantee that TPPs have the new key before the old one is retired.
PART 3: JWE — Encryption for Confidentiality
3.1 The JWE Architecture (RFC 7516)
JWE encrypts the payload. The encryption process is a 5-step cryptographic pipeline:
-
Generate a Content Encryption Key (CEK) : A random AES-GCM symmetric key (e.g., 256 bits).
-
Encrypt the Payload: Use the CEK to encrypt the plaintext with AES-GCM, producing a ciphertext and an authentication tag.
-
Encrypt the CEK: Use the recipient’s RSA public key to encrypt the CEK using RSA-OAEP. This produces an encrypted key.
-
Serialize: Compose the JWE Compact Serialization:
Header.Base64Url || '.' || Encrypted_Key.Base64Url || '.' || IV.Base64Url || '.' || Ciphertext.Base64Url || '.' || Tag.Base64Url -
Decryption: The recipient uses their private key to decrypt the CEK, then uses the CEK to decrypt the ciphertext.
Byte-Size Overhead:
-
Encrypted Key (RSA-2048): 256 bytes → Base64 ~344 bytes.
-
IV: 96 bits → 16 bytes → Base64 ~22 bytes.
-
Tag: 128 bits → 16 bytes → Base64 ~22 bytes.
-
Ciphertext (Payload size + overhead): ~700 bytes.
-
Total JWE Size: ~1.1 KB (slightly larger than a signed JWT).
3.2 Latency of JWE Encryption/Decryption
-
RSA-OAEP (Asymmetric) : Encrypting the CEK takes ~2ms (public key operation). Decryption takes ~5ms (private key operation).
-
AES-GCM (Symmetric) : Encrypting/decrypting the payload takes ~0.1ms (hardware accelerated).
-
Total JWE Latency: 2.1ms (encryption) and 5.1ms (decryption).
Trade-off: JWE is slower than JWS, but necessary for long-term storage and ultra-sensitive payloads (e.g., PII in the audit trail). For high-throughput API requests (e.g., fetching account balances), we avoid JWE and rely solely on mTLS (transport encryption) and JWS (integrity).
PART 4: THE JWKS KEY LIFE CYCLE — A Formalized Schedule
The ASPSP manages a key set (JWKS) for JWS signing and JWE encryption. The lifecycle consists of four phases:
-
Generation: The ASPSP generates a new key pair using a Hardware Security Module (HSM) with an entropy source.
-
Publication: The new public key is added to the JWKS endpoint, with a
kidand anexp(expiry) field. -
Overlap: The old and new keys coexist for
T_overlap = 16 hours(as derived earlier). -
Retirement: The old key is removed from the JWKS. Any TPP that still uses the old
kidfor signature verification will receive a validation error and must refresh their JWKS cache.
The Expiry Calculus:
We set the key expiration to 90 days (T_lifetime = 7776000 seconds) to comply with the OBIE’s certificate rotation mandate. This means the ASPSP must generate a fresh key pair every 90 days.
CLOSING — THE COMPLETE CRYPTOGRAPHIC STACK
You have now integrated payload-level security (JWS/JWE) with transport-level security (mTLS). The final security architecture is a layered cake:
-
Layer 1 (Transport): mTLS with ECDHE (PFS) and AES-GCM.
-
Layer 2 (Integrity): JWS (PS256) for tokens, assertions, and JARM responses.
-
Layer 3 (Confidentiality): JWE (AES-GCM + RSA-OAEP) for audit trails and sensitive consent payloads.
Operational Risk: If the ASPSP signs the JWT with an expired private key (beyond the 90-day rotation), TPPs will reject the JWT, causing a catastrophic failure. The certified practitioner must automate the key generation and JWKS publication pipeline, with monitoring to ensure the rotation completes successfully.