← Payment Reference GuidesKey Management Standards

TR-31 & TR-34

The two foundational ANSI X9 standards for secure cryptographic key exchange between Hardware Security Modules. TR-31 defines the key block format that binds usage attributes to the key value. TR-34 defines the RSA-based protocol for distributing those key blocks from a Key Distribution Host to receiving devices without human key ceremonies.

ANSI X9.143PCI HSMHSM Key ExchangeRSA-OAEPCMS / ASN.1

TR-34 Key Distribution Protocol (X9 TR34-2012)

TR-34 defines how a Key Distribution Host (KDH) distributes symmetric keys to a Key Receiving Device (KRD) using RSA asymmetric cryptography. The protocol uses hybrid encryption: a fresh ephemeral key KE encrypts the key payload (the Block Encrypted, BE), then RSA-OAEP encrypts only the small KE — this is how CMS EnvelopedData works in practice. A Bind Phase must establish mutual certificate trust before any key transport token can be issued.

Animated protocol — two-pass & one-pass

Remote symmetric key (KEK) distribution to an HSM/terminal using RSA. The two-pass protocol binds the key to a fresh nonce from the receiving device to prevent replay.

1 / 4
🖥️KRDKey Receiving Device
🏛️KDHKey Distribution Host
1
Credential Request
2
Build Key Token
3
Key Token Sent
4
Verify & Install
Key Request

Credential Request

KRD sends its certificate and a fresh random nonce (RKRD).

The Key Receiving Device proves its identity with a certificate chained to a trusted CA and supplies a random number so the host can bind the key token to this specific request.

Key Request
Key Token
Verify / Install

Protocol Phases

1

Bind Phase

KRD sends CTKRD (CertKRD) to KDH. KDH responds with CTKDH (CertKDH + CRLCA_KDH). Mutual credentials established.

2

Key Transport

2-pass: KRD sends RTKRD (nonce) → KDH sends KTKDH. 1-pass: KDH sends KTKDH with timestamp only. Both use ephemeral key KE.

3

Key Verification

KRD computes KCV(Kn) and returns it to KDH. KDH confirms the correct key was received and loaded successfully.

4

Unbind / Rebind

KDH sends UBTKDH or RBTKDH. Four scenarios (Table 2): physical reset, KDH unbind, new KDH rebind, or CA-authorised rebind.

Actors & Token Glossary

🏦

KDH — Key Distribution Host

Bank, processor, or key management server. Generates and distributes symmetric keys. Holds a CA-signed RSA certificate (CertKDH) with private key in its HSM.

Sends: CTKDH, KTKDH, UBTKDH, RBTKDHSigns tokens with PrivKDHEncrypts ephemeral KE with KRD's public key
RSA
🏧

KRD — Key Receiving Device

ATM EPP, POS terminal HSM, card bureau HSM, or gateway HSM. Each KRD holds a CA-signed RSA certificate (CertKRD) with private key sealed in its tamper-resistant boundary.

Sends: CTKRD, RTKRDVerifies KTKDH signature using CertKDHDecrypts EncryptedKey with PrivKRD to recover KE
TokenFull NameDirectionDescription
CTKRDKRD Credential TokenKRD → KDHCertKRD. Sent during Bind Phase. Gives KDH the KRD's RSA public key for encrypting future EncryptedKey values.
CTKDHKDH Credential TokenKDH → KRDCertKDH + CRLCA_KDH. KDH's signing certificate and its CA's CRL. Stored by KRD for verifying KTKDH tokens.
RTKRDKRD Random Number TokenKRD → KDHRKRD — 8-byte random nonce. 2-pass only. Embedded inside the signed KTKDH payload to bind it to this session.
KTKDHKDH Key Transport TokenKDH → KRDMain key delivery token. Contains: KBH (cleartext), EncryptedKey = RSA-OAEP(PubKRD, KE), BE = EKE(Version ‖ IDKDH_CRED ‖ Kn ‖ KBH), Signature, CRLCA_KDH.
UBTKDHKDH Unbind TokenKDH → KRDInstructs KRD to delete working keys. Signed by the current KDH.
RBTKDHKDH Rebind TokenNew KDH → KRDCurrent KDH authorises a new KDH to take over. KRD verifies current KDH's signature before accepting.
UBTCA_UNBINDCA Unbind TokenCA → KRDHigher Level Authority — CA unbinds the KRD when current KDH is unavailable (e.g., compromised, dissolved).
RBTCA_UNBINDCA Rebind TokenCA → KRDHigher Level Authority — CA authorises rebind to a new KDH when current KDH cannot act.

Phase 1 — Bind Phase (Credential Exchange)

Before any key can be transported, the KDH and KRD must exchange and validate each other's X.509 credentials. This creates the trust relationship that all future KTKDH tokens depend on. No KTKDH token is valid unless the Bind Phase has been completed first.

KRD
KDH
A1

Send CTKRD (KRD Credential Token)

KRD sends its X.509 certificate to the KDH as a KRD Credential Token (CTKRD). CertKRD contains the KRD's RSA public key (2048-bit minimum, exponent e=65537) signed by the shared CA. KDH will use this public key to encrypt future EncryptedKey values.

CTKRD = { CertKRD }
CTKRD →
B1

Validate CertKRD & store

KDH verifies CertKRD against the CA root. Checks: certificate chain, validity period, CRL revocation status, keyUsage extension includes keyEncipherment, RSA key size ≥ 2048-bit. Stores CertKRD on success for building future KTKDH tokens.

Verify: chain(CertKRD) → CA root  |  keyUsage = keyEncipherment  |  store CertKRD
B2

Send CTKDH (KDH Credential Token)

KDH sends its signing certificate (CertKDH) together with the CA's current Certificate Revocation List (CRLCA_KDH). The KRD stores both — CertKDH to verify future KTKDH signatures, and CRLCA_KDH to check that CertKDH has not been revoked without an online lookup.

CTKDH = { CertKDH ‖ CRLCA_KDH }
← CTKDH
A2

Validate CTKDH & store credentials

KRD validates CertKDH against the CA root. Checks CRLCA_KDH to confirm CertKDH is not revoked. Stores both in the KRD's secure storage — these credentials are used to authenticate every KTKDH token received from this KDH going forward.

store( CertKDH, CRLCA_KDH ) in KRD secure boundary

Phase 2 — 2-Pass Key Transport Protocol

The KRD initiates by sending a random nonce RKRD. The KDH uses hybrid encryption: it generates an ephemeral key KE, encrypts the entire key payload with KE (producing BE), then RSA-OAEP encrypts only the small KE value (producing EncryptedKey). Both components go into the signed KTKDH token alongside the cleartext KBH and the KDH's signature over the entire body.

KRD
KDH
A1

Generate nonce & send RTKRD

KRD generates an 8-byte random nonce (RKRD) and sends it as a KRD Random Number Token (RTKRD). This nonce will be embedded inside the signed portion of the KTKDH response — the KRD verifies it matches on receipt, preventing replay attacks even on a first-time load when there is no shared session state.

RTKRD = { RKRD }  // 8 random bytes
RTKRD →
B1

Receive & store RKRD

KDH receives and stores RKRD. It will be placed in the cleartext signed portion of the KTKDH token, so the KRD can verify the token was built specifically in response to this request.

B2

Generate Kn (symmetric working key) & KBH

KDH generates (or retrieves) the symmetric working key Kn to be transported — a 3DES or AES key that the KRD will use for live transactions. KDH also constructs the TR-31 Key Block Header (KBH) describing Kn: key usage, algorithm, mode of use, exportability, and key version.

Kn = random symmetric key  |  KBH = TR-31 header (usage / algo / mode / export)
B3

Generate ephemeral key KE

KDH generates a fresh random ephemeral symmetric key KE — either TDEA 192-bit or AES-128 (per Annex A). KE encrypts the key payload and is discarded after the token is built. Each KTKDH token uses an independent KE — this provides forward secrecy: compromise of one token cannot decrypt another.

KE = random ephemeral TDEA-192 or AES-128  // never reused
B4

Encrypt key block: BE = EKE(Version ‖ IDKDH_CRED ‖ Kn ‖ KBH)

KDH encrypts the full key payload using KE. The payload includes the protocol Version, the KDH Credential Identifier (IDKDH_CRED — a fingerprint derived from CertKDH), the transported key Kn, and a copy of KBH. Including IDKDH_CRED inside the encrypted envelope is a security critical step: it prevents signature-stripping attacks by binding the encrypted payload cryptographically to the specific KDH identity.

BE = EKE( Version ‖ IDKDH_CRED ‖ Kn ‖ KBH )
B5

Encrypt ephemeral key: EncryptedKey = RSA-OAEPPubKRD(KE)

KDH encrypts the ephemeral key KE using RSA-OAEP (OID 1.2.840.113549.1.1.7) with SHA-256 and the KRD's RSA public key from CertKRD. Only the KRD's HSM holds the matching RSA private key (PrivKRD) and can decrypt this to recover KE.

EncryptedKey = RSA-OAEPPubKRD, SHA-256( KE )
B6

Assemble & sign KTKDH token

KDH assembles the complete Key Transport Token. The body (RKRD ‖ KBH ‖ EncryptedKey ‖ BE) is signed with sha256WithRSAEncryption (OID 1.2.840.113549.1.1.11). Finally, CRLCA_KDH is appended so the KRD can check revocation without a network call.

KTKDH = RKRD ‖ KBH ‖ EncryptedKey ‖ BE ‖ SKDH(RKRD ‖ KBH ‖ EncryptedKey ‖ BE) ‖ CRLCA_KDH
← KTKDH
A2

Verify KTKDH signature & check RKRD

KRD verifies the RSA signature using CertKDH (stored during Bind Phase). Checks CRLCA_KDH embedded in the token to ensure CertKDH is not revoked. Verifies that the RKRD in the token matches the nonce sent in A1 — confirming this token was built for this session and is not a replay.

Verify SKDH(RKRD ‖ KBH ‖ EncryptedKey ‖ BE)  |  Assert: token RKRD == sent RKRD
A3

Decrypt KE → decrypt BE → verify IDKDH_CRED & KBH

KRD decrypts EncryptedKey with PrivKRD to recover KE. Decrypts BE with KE to recover (Version, IDKDH_CRED, Kn, KBH_inner). KRD asserts: (1) IDKDH_CRED matches the stored CertKDH fingerprint — blocks signature-stripping; (2) KBH_inner matches the cleartext KBH — blocks cleartext header tampering.

KE = DPrivKRD(EncryptedKey)  |  (Ver, ID, Kn, KBH) = DKE(BE)  |  Assert ID == CertKDH fingerprint && KBH == cleartext KBH
A4

Load Kn & compute KCV

KRD loads Kn into its secure boundary under the key usage, algorithm, and mode specified by KBH. Computes Key Check Value: KCV(Kn) = lower 3 bytes of 3DES-ECB(Kn, all-zeros block). Returns KCV to KDH for cross-verification.

KCV(Kn) = 3DES-ECBKn( 0x0000000000000000 )[0:3]

Phase 2 (alternate) — 1-Pass Key Transport

In 1-pass mode the KRD does not send a nonce. A Timestamp replaces RKRD inside the signed token for replay prevention. The same hybrid encryption (ephemeral KE + RSA-OAEP) is used. The KRD's certificate must be pre-configured at the KDH before tokens can be built offline.

1-pass KTKDH formula:

BE = EKE( Version ‖ IDKDH_CRED ‖ Kn ‖ KBH )
EncryptedKey = RSA-OAEPPubKRD( KE )
KTKDH = KBH ‖ EncryptedKey ‖ BE ‖ Timestamp ‖ SKDH( KBH ‖ EncryptedKey ‖ BE ‖ Timestamp ) ‖ CRLCA_KDH

KRD enforces a replay window (typically ±5 minutes) and must reject any KTKDH whose timestamp falls outside the window or that duplicates a previously accepted timestamp.

Batch key distribution: 1-pass lets a processor pre-generate KTKDH tokens for tens of thousands of terminals offline and deliver them over a terminal management system over hours or days. Each token's Timestamp must fall within the device's replay window at the moment it is consumed — so delivery timing must be managed.

KTKDH Token — Complete Structure

The KTKDH is a CMS (Cryptographic Message Syntax, ANS X9.73 / RFC 5652) SignedData structure. The Key Block Header (KBH) appears twice: once in cleartext as part of the signed data (for efficient inspection of key metadata), and once inside the encrypted BE. The KRD must verify both copies match — any tampering of the cleartext KBH is detected immediately.

KTKDH — KDH Key Transport Token (CMS SignedData)
RKRD (2-pass) or Timestamp (1-pass) — cleartext, signed2-pass: 8-byte KRD nonce. 1-pass: UTC timestamp. Included in the signed data body. KRD verifies against its stored nonce or against the replay window.
KBH — TR-31 Key Block Header — cleartext, signedPlaintext TR-31 header describing key usage, algorithm, mode, and exportability. KRD can inspect without decrypting. Must match the KBH inside BE — tampering of this cleartext copy is detected at A3.
EncryptedKey = RSA-OAEPPubKRD(KE) — cleartext, signedThe ephemeral key KE encrypted with KRD's RSA public key. KRD decrypts with PrivKRD to recover KE, which is then used to decrypt BE.
BE = EKE(Version ‖ IDKDH_CRED ‖ Kn ‖ KBH) — encrypted with KE
VersionProtocol version identifier for forward compatibility
IDKDH_CRED — KDH Credential IdentifierFingerprint of CertKDH. Prevents signature-stripping attacks — an attacker cannot re-sign the token as a different KDH because this value inside the encrypted payload is bound to the original KDH's certificate. KRD asserts it matches stored CertKDH fingerprint.
Kn — Transported Symmetric KeyThe 3DES (128 or 192-bit) or AES-128 working key. Never transmitted in cleartext at any point in the protocol.
KBH (inner) — TR-31 Key Block HeaderDuplicate of the cleartext KBH. KRD asserts inner KBH == cleartext KBH at step A3. Mismatch means the cleartext header was tampered with — token must be rejected.
SKDH(RKRD ‖ KBH ‖ EncryptedKey ‖ BE) — RSA Signaturesha256WithRSAEncryption (OID 1.2.840.113549.1.1.11) by KDH's private key over all four preceding fields. KRD verifies with stored CertKDH.
CRLCA_KDH — Certificate Revocation ListCA's current CRL. Always included in every KTKDH token so the KRD can verify CertKDH has not been revoked without an online query. KRD checks this before accepting the token.

Signature-stripping attack & how IDKDH_CRED defeats it: Without IDKDH_CRED inside BE, an attacker who obtained a valid KTKDH from KDH-A could strip the outer signature and re-sign the token with their own key to impersonate KDH-B. Because IDKDH_CRED is encrypted inside BE and is locked to KDH-A's certificate fingerprint, any attempt to re-sign with a different KDH's key fails: when KRD decrypts BE, IDKDH_CRED will not match the stored CertKDH fingerprint of the alleged signer, and the token is rejected.

Phase 4 — Unbind & Rebind Scenarios (Table 2)

The X9 TR34-2012 spec (Table 2) defines four scenarios for removing or transferring a KRD's binding. The appropriate token type depends on whether the current KDH is available and who has authority to authorise the change.

#ScenarioInitiatorTokensWhen to Use
1Physical ResetOperatorNoneDevice is physically present. Authorised technician resets device to factory/unbound state. No cryptographic token needed.
2KDH UnbindCurrent KDHUBTKDHKDH is available and initiates decommission or rotation. KDH sends signed UBTKDH; KRD verifies signature and deletes working keys.
3New KDH RebindNew KDHRBTKDHKRD transferred to a new KDH (e.g., processor change). Current KDH signs RBTKDH containing new KDH credentials, authorising the transfer. KRD verifies current KDH's signature before accepting new relationship.
4Higher Level Authority RebindCAUBTCA_UNBIND + RBTCA_UNBINDCurrent KDH is unavailable (compromised, dissolved, or unreachable). The CA acts as Higher Level Authority, signing UBTCA_UNBIND to unbind and RBTCA_UNBIND to authorise a new KDH.

Cryptographic Algorithm Support (Annex A)

X9 TR34-2012 Annex A specifies supported and deprecated algorithm choices. SHA-256 with RSA-OAEP is the current mandatory choice; SHA-1 variants are deprecated.

PurposeAlgorithmOIDStatus
Token Signaturesha256WithRSAEncryption1.2.840.113549.1.1.11Supported
Token Signaturesha1WithRSAEncryption1.2.840.113549.1.1.5Deprecated
Asymmetric EncryptionRSAES-OAEP (id-RSAES-OAEP)1.2.840.113549.1.1.7Supported
Asymmetric EncryptionRSAES-PKCS1-v1_51.2.840.113549.1.1.1Not Supported
RSA Key Size2048-bit, exponent e=65537Required
Ephemeral Key (KE)TDEA 192-bit (triple-length 3DES)Supported
Ephemeral Key (KE)AES-128Supported
Transported Key (Kn)TDEA 128-bit (2-key 3DES)Supported
Transported Key (Kn)TDEA 192-bit (3-key 3DES)Supported
Transported Key (Kn)AES-128Supported

KRD Lifecycle — Full State Machine

🏭

Unbound (Factory)

RSA key-pair generated in HSM at manufacture. CA-signed CertKRD installed. No symmetric working keys. No KDH relationship established.

Bind Phase — KRD sends CTKRD; KDH responds with CTKDH
🤝

Credentials Exchanged

KRD holds CertKDH + CRLCA_KDH. KDH holds CertKRD. Mutual trust established. Ready to accept KTKDH tokens.

2-pass: RTKRD → KTKDH  |  1-pass: KTKDH only
🔒

Bound

Working key Kn loaded under KBH-specified attributes. KCV verified. Device processes live transactions. Cryptographically bound to this KDH.

UBTKDH (KDH-initiated) / UBTCA_UNBIND (CA) / physical reset
🔓

Unbound

Working keys deleted. RSA key-pair still valid. Must re-run Bind Phase or process RBTKDH / RBTCA_UNBIND to receive new keys.

RBTKDH (current KDH signs) or RBTCA_UNBIND (CA signs)(returns to Credentials Exchanged)