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.
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.
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.
Protocol Phases
Bind Phase
KRD sends CTKRD (CertKRD) to KDH. KDH responds with CTKDH (CertKDH + CRLCA_KDH). Mutual credentials established.
Key Transport
2-pass: KRD sends RTKRD (nonce) → KDH sends KTKDH. 1-pass: KDH sends KTKDH with timestamp only. Both use ephemeral key KE.
Key Verification
KRD computes KCV(Kn) and returns it to KDH. KDH confirms the correct key was received and loaded successfully.
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.
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.
| Token | Full Name | Direction | Description |
|---|---|---|---|
CTKRD | KRD Credential Token | KRD → KDH | CertKRD. Sent during Bind Phase. Gives KDH the KRD's RSA public key for encrypting future EncryptedKey values. |
CTKDH | KDH Credential Token | KDH → KRD | CertKDH + CRLCA_KDH. KDH's signing certificate and its CA's CRL. Stored by KRD for verifying KTKDH tokens. |
RTKRD | KRD Random Number Token | KRD → KDH | RKRD — 8-byte random nonce. 2-pass only. Embedded inside the signed KTKDH payload to bind it to this session. |
KTKDH | KDH Key Transport Token | KDH → KRD | Main key delivery token. Contains: KBH (cleartext), EncryptedKey = RSA-OAEP(PubKRD, KE), BE = EKE(Version ‖ IDKDH_CRED ‖ Kn ‖ KBH), Signature, CRLCA_KDH. |
UBTKDH | KDH Unbind Token | KDH → KRD | Instructs KRD to delete working keys. Signed by the current KDH. |
RBTKDH | KDH Rebind Token | New KDH → KRD | Current KDH authorises a new KDH to take over. KRD verifies current KDH's signature before accepting. |
UBTCA_UNBIND | CA Unbind Token | CA → KRD | Higher Level Authority — CA unbinds the KRD when current KDH is unavailable (e.g., compromised, dissolved). |
RBTCA_UNBIND | CA Rebind Token | CA → KRD | Higher 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.
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 }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 CertKRDSend 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 }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 boundaryPhase 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.
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 bytesReceive & 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.
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)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 reusedEncrypt 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 )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 )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_KDHVerify 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 RKRDDecrypt 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 KBHLoad 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_KDHKRD 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.
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.
| # | Scenario | Initiator | Tokens | When to Use |
|---|---|---|---|---|
| 1 | Physical Reset | Operator | None | Device is physically present. Authorised technician resets device to factory/unbound state. No cryptographic token needed. |
| 2 | KDH Unbind | Current KDH | UBTKDH | KDH is available and initiates decommission or rotation. KDH sends signed UBTKDH; KRD verifies signature and deletes working keys. |
| 3 | New KDH Rebind | New KDH | RBTKDH | KRD 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. |
| 4 | Higher Level Authority Rebind | CA | UBTCA_UNBIND + RBTCA_UNBIND | Current 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.
| Purpose | Algorithm | OID | Status |
|---|---|---|---|
| Token Signature | sha256WithRSAEncryption | 1.2.840.113549.1.1.11 | Supported |
| Token Signature | sha1WithRSAEncryption | 1.2.840.113549.1.1.5 | Deprecated |
| Asymmetric Encryption | RSAES-OAEP (id-RSAES-OAEP) | 1.2.840.113549.1.1.7 | Supported |
| Asymmetric Encryption | RSAES-PKCS1-v1_5 | 1.2.840.113549.1.1.1 | Not Supported |
| RSA Key Size | 2048-bit, exponent e=65537 | — | Required |
| Ephemeral Key (KE) | TDEA 192-bit (triple-length 3DES) | — | Supported |
| Ephemeral Key (KE) | AES-128 | — | Supported |
| Transported Key (Kn) | TDEA 128-bit (2-key 3DES) | — | Supported |
| Transported Key (Kn) | TDEA 192-bit (3-key 3DES) | — | Supported |
| Transported Key (Kn) | AES-128 | — | Supported |
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.
Credentials Exchanged
KRD holds CertKDH + CRLCA_KDH. KDH holds CertKRD. Mutual trust established. Ready to accept KTKDH tokens.
Bound
Working key Kn loaded under KBH-specified attributes. KCV verified. Device processes live transactions. Cryptographically bound to this KDH.
Unbound
Working keys deleted. RSA key-pair still valid. Must re-run Bind Phase or process RBTKDH / RBTCA_UNBIND to receive new keys.