Project Documentation
·
API Endpoints
·
Community
·
Blog
A Go library implementing the TR-31 (ANSI X9.143) key block standard for secure cryptographic key exchange.
TR-31 is a method defined by ASC X9.143 for secure cryptographic key exchange between devices and systems, particularly in the financial industry. This format provides a structured way to protect sensitive key material while maintaining essential metadata about key usage, algorithms, and other attributes.
moov-io/tr31 is undergoing active development and testing within Moov. Please star the project and share feedback, bugs, questions, etc in the tr31
channel in slack. If you find security vulnerabilities reach out to [email protected]
.
- Supports all major TR-31 key block versions:
- Version A (TDES variant)
- Version B (TDES key derivation - preferred TDES implementation)
- Version C (TDES variant)
- Version D (AES key derivation)
- Implements multiple encryption algorithms:
- Triple DES (TDES)
- Single DES (legacy)
- AES
- Comprehensive error handling with detailed error messages
- Thread-safe operations
- No external dependencies
go get github.com/moov-io/tr31
package main
import (
"fmt"
"github.com/moov-io/tr31/pkg/tr31"
)
func main() {
// Create a new header with TR-31 version B
header, err := encryption.NewHeader(
encryption.TR31_VERSION_D, // Version ID
"B0", // Key Usage (Data Encryption Key)
"A", // Algorithm (AES)
"E", // Mode of Use (Encrypt)
"01", // Version Number
"X", // Exportability (Exportable with restrictions)
)
if err != nil {
panic(err)
}
// Create a key block with your Key Block Protection Key (KBPK)
kbpkopts := KBPKOptions{
Version: "D",
KeyLength: 32,
}
kbpk, _ := GenerateKBPK(kbpkopts)
// Create a new KeyBlock
keyBlock, err := encryption.NewKeyBlock(kbpk, header)
if err != nil {
panic(err)
}
// Wrap a key
keyToWrap := []byte{...} // Your key to wrap
wrappedKey, err := keyBlock.Wrap(keyToWrap, nil)
if err != nil {
panic(err)
}
// Unwrap a key
unwrappedKey, err := keyBlock.Unwrap(wrappedKey)
if err != nil {
panic(err)
}
}
func (kb *KeyBlock) Wrap(key []byte, maskedKeyLen *int) (string, error)
Wraps a cryptographic key using the TR-31 format.
Parameters:
key
: The key to be wrapped (byte slice)maskedKeyLen
: Optional pointer to an integer specifying the masked key length. If nil, uses the maximum key size for the algorithm.
Returns:
string
: The wrapped key block in TR-31 formaterror
: Any error that occurred during the wrapping process
func (kb *KeyBlock) Unwrap(keyBlock string) ([]byte, error)
Unwraps a TR-31 formatted key block to retrieve the original key.
Parameters:
keyBlock
: The TR-31 formatted key block string to unwrap
Returns:
[]byte
: The unwrapped keyerror
: Any error that occurred during the unwrapping process
The library supports different TR-31 versions with specific characteristics:
-
Version A/C:
- Uses TDES encryption
- Simple key derivation (XOR with constants)
- 4-byte MAC
-
Version B:
- Uses TDES encryption
- CMAC-based key derivation
- 8-byte MAC
- Recommended for TDES implementations
-
Version D:
- Uses AES encryption
- CMAC-based key derivation
- 16-byte MAC
- Supports AES-128, AES-192, and AES-256
- Always use strong, random Key Block Protection Keys (KBPK)
- Version B is preferred over Version A/C for TDES implementations
- Version D (AES) is recommended for new implementations
- The library performs key length validation and padding automatically
- Ensure your Go environment and dependencies are up to date
The library provides detailed error messages through two custom error types:
HeaderError
: For issues related to TR-31 header processingKeyBlockError
: For issues related to key block processing
Unwraps a TR-31 formatted key block to retrieve the original key.
Running tool: /opt/homebrew/bin/go test -benchmem -run=^$ -bench ^BenchmarkUnwrap_D_32_WithSetup$ github.com/moov-io/tr31/pkg/tr31
goos: darwin
goarch: arm64
pkg: github.com/moov-io/tr31/pkg/tr31
cpu: Apple M1 Pro
BenchmarkUnwrap_D_32_WithSetup-10 301116 3619 ns/op 8608 B/op 64 allocs/op
tr31 is a tool for managing both 3DES and AES-derived unique keys per transaction (TR-31) key management.
tr31 [-v] [-algorithm] [-e] [-d]
tr31 -v
Print the version of tr31 (Example: v1.0.0)
tr31 -e
Encrypt a card data block using the TR-31 transaction key
tr31 -d
Decrypt a card data block using the TR-31 transaction key
-vault_address string
Vault address where the encryption/decryption key is stored
-vault_token string
Vault token for authentication
-key_path string
Path to the encryption/decryption key in the vault
-key_name string
Name of the encryption/decryption key in the vault
-wrapper_key string
Symmetric key
-key_block string
Wrapped key block for decryption
tr31 -e -vault_address="https://vault-cluster....com:8200" -vault_token="hvs.CA******Ak" -key_path="kv/.../key" -key_name="wrapper_key" -wrapper_key="A0088******A356E"
tr31 -d -vault_address="https://vault-cluster....com:8200" -vault_token="hvs.CA******Ak" -key_path="kv/.../key" -key_name="kbkp" -key_block="A0088******A356E"
TR31 library provided web server. Please check following http endpoints
Method | Request Body | Route | Action |
---|---|---|---|
POST | JSON | /encrypt_data | Encrypt Data |
POST | JSON | /decrypt_data | Decrypt Data |
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Note: This implementation is provided as-is. Users should verify the implementation meets their security requirements before using in production environments.