Token Management MLE Keys {#uctp-keys-tms-mle-keys}
===================================================

When a checkout is completed with the payloadTypeIndicatorCheckout field set to `FULL`, the checkout response includes the encryptedPayload field which contains sensitive PCI/PII data. This sensitive data includes the actual card number (or token), expiration date, billing address, consumer details, and dynamic cryptogram data. This payload is encrypted by c`Cybersource` using Message-Level Encryption (MLE) so that only the authorized payment service provider (PSP) can read it.  
MLE keys are required when the payloadTypeIndicatorCheckout field is set to `FULL` in the checkout request. When the field is set to `SUMMARY`, the encryptedPayload field is not present and the MLE key is not required. MLE keys are also required when the decrypted payload is needed to obtain the actual payment credentials (PAN or token, cryptogram) for downstream payment processing, such as authorization through `Cybersource` or another processor.  
The public key is generated by the PSP or by the merchant, and uploaded to the `Cybersource` `Business Center` in the Key Management section. `Cybersource` uses this public key to encrypt the checkout payload. The private key is securely retained by the PSP or merchant and is never shared. It is preferably used on server-side to decrypt the encryptedPayload JWE. This design ensures that even `Cybersource` cannot read the decrypted payload after encryption and only the entity holding the private key can access the cardholder data. This is critical for ensuring PCI DSS compliance.

Use Encryption Keys {#uctp-keys-tms-mle-keys_section_rn3_pv4_53c}
-----------------------------------------------------------------

This table shows how encryption keys are used:

|         Key Aspect         |                                                   Details                                                    |
|----------------------------|--------------------------------------------------------------------------------------------------------------|
| Generating Party           | PSP or merchant                                                                                              |
| Public Key Upload Location | `Business Center` \&gt; Key Management (Token Management MLE section)                                        |
| Format                     | Base64-encoded RSA public key                                                                                |
| Private Key Storage        | PSP or merchant, in a secure key vault or HSM                                                                |
| Purpose                    | Decrypt `encryptedPayload` JWE in checkout responses                                                         |
| Encryption Format          | JWE Compact Serialization (RSA-OAEP-256 / A256GCM)                                                           |
| Payload Contents           | Card or token data, billing address, consumer email/name/phone, shipping address, dynamic data (cryptograms) |
[Encryption Key Responsibilities and Usage]

Key Setup {#uctp-keys-tms-mle-keys_section_vfg_4v4_53c}
-------------------------------------------------------

Follow these steps to set up your key:

1. Generate an RSA key pair (minimum 2048-bit, recommended 4096-bit).
2. Extract the public key in Base64 format.
3. Upload the public key in `Business Center` \&gt; Key Management.
4. Store the private key securely on your server (key vault, HSM, or encrypted secrets store).
   {#uctp-keys-tms-mle-keys_ol_stq_s1p_53c}  
   When you need to rotate the key, you must generate a new key pair, upload the new public key to `Business Center`, and update your server with the new private key. `Cybersource` uses the new public key for subsequent checkout responses. You must keep the old private key available temporarily to decrypt any in-flight responses that were encrypted with the previous key.

JavaScript Example: Decrypt Checkout Payload {#uctp-keys-tms-mle-keys_section_q2k_gw4_53c}
------------------------------------------------------------------------------------------

```
const crypto = require('crypto');

async function decryptPayload(jweCompact, privateKeyPem) {
  const [headerB64, encKeyB64, ivB64, ciphertextB64, tagB64] = jweCompact.split('.');

  // Import the merchant's private key
  const privateKey = crypto.createPrivateKey(privateKeyPem);

  // Unwrap the content encryption key (CEK)
  const wrappedKey = base64UrlDecode(encKeyB64);
  const cek = crypto.privateDecrypt(
    { key: privateKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, oaepHash: 'sha256' },
    wrappedKey
  );

  // Decrypt the payload with AES-256-GCM
  const iv = base64UrlDecode(ivB64);
  const ciphertext = base64UrlDecode(ciphertextB64);
  const authTag = base64UrlDecode(tagB64);
  const aad = Buffer.from(headerB64, 'ascii');

  const decipher = crypto.createDecipheriv('aes-256-gcm', cek, iv);
  decipher.setAAD(aad);
  decipher.setAuthTag(authTag);

  const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
  return JSON.parse(decrypted.toString());
}

// Usage: decrypt the encryptedPayload from a checkout response
const payload = await decryptPayload(checkoutResponse.encryptedPayload, merchantPrivateKey);
// payload contains: { card, billingAddress, consumerEmailAddress, dynamicData, ... }
```

{#uctp-keys-tms-mle-keys_codeblock_vjx_fw4_53c}

Key Summary {#uctp-keys-tms-mle-keys_section_gjy_4w4_53c}
---------------------------------------------------------

|            Key             |  Side  |                                                Source                                                |                                   When Used                                    |                                             Purpose                                             |
|----------------------------|--------|------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------|
| API Authentication Keys    | Server | `Business Center` credentials.                                                                       | Every server-to-server API call                                                | Authenticate requests to `Cybersource` (`/uctp/v1/sessions` and `/flex/v2/public-keys/{kid}`) . |
| JWT Validation Key (`kid`) | Server | Retrieved from `/flex/v2/public-keys/{kid}` per JWT                                                  | Every JWT received (capture context, checkout response, inner credentials JWT) | Verify JWT signature integrity and reject tampered tokens.                                      |
| PAN Encryption Keys        | Client | Extracted from capture context JWT at `ctx[0].data.paymentConfigurations.[NETWORK].panEncryptionKey` | Guest checkout flow only when consumer enters card manually.                   | JWE-encrypt card data so raw PAN does not travel unencrypted.                                   |
| Token Management MLE Key   | Server | RSA key pair generated by PSP and the public key is uploaded to the `Business Center`.               | Checkout responses with payloadTypeIndicatorCheckout set to `FULL`.            | Decrypt encryptedPayload to access PCI/PII payment credentials.                                 |
[Keys Used in Checkout and Tokenization Flows]

