Dukpt
ANSI X9.24 DUKPT libraries and tools
Install / Use
/learn @moov-io/DukptREADME
moov-io/dukpt
This project implements the ANSI X9.24-3:2017 standard for TDES and AES Derived Unique Key Per Transaction (DUKPT) key management. Since most uses of this standard involve dedicated security hardware, this implementation is mostly for validation and debugging.
Table of contents
- Project status
- Usage
- Supported and tested platforms
- Contributing
- Releasing
- Testing
- Related projects
- License
Project status
Moov dukpt is actively used for validation and debugging. Please star the project if you are interested in its progress. If you have layers above dukpt to simplify tasks, perform business operations, or found bugs we would appreciate an issue or pull request. Thanks!
Usage
Go library
This project uses Go Modules and Go v1.18 or newer. See Golang's install instructions for help setting up Go. You can download the source code and we offer tagged and released versions as well. We highly recommend you use a tagged release for production.
$ git@github.com:moov-io/dupkt.git
$ go get -u github.com/moov-io/dupkt
DUPKT apis
Moov dukpt project supported general utility functions for managing transaction key. The functions divided into two group as aes and des
- Functions for triple data encryption algorithm (des)
func DerivationOfInitialKey(bdk, ksn []byte) ([]byte, error)
func DeriveCurrentTransactionKey(ik, ksn []byte) ([]byte, error)
func EncryptPin(currentKey []byte, pin, pan string, format string) ([]byte, error)
func DecryptPin(currentKey, ciphertext []byte, pan string, format string) (string, error)
func GenerateMac(currentKey []byte, plainText, action string) ([]byte, error)
func EncryptData(currentKey, iv []byte, plainText, action string) ([]byte, error)
func DecryptData(currentKey, ciphertext, iv []byte, action string) (string, error)
- Functions for advanced encryption standard (aes)
func DerivationOfInitialKey(bdk, kid []byte) ([]byte, error)
func DeriveCurrentTransactionKey(ik, ksn []byte) ([]byte, error)
func EncryptPin(currentKey, ksn []byte, pin, pan string, keyType string) ([]byte, error)
func DecryptPin(currentKey, ksn, ciphertext []byte, pan string, keyType string) (string, error)
func GenerateCMAC(currentKey, ksn []byte, plaintext string, keyType string, action string) ([]byte, error)
func GenerateHMAC(currentKey, ksn []byte, plaintext string, keyType string, action string) ([]byte, error)
func EncryptData(currentKey, ksn, iv []byte, plaintext, keyType, action string) ([]byte, error)
func DecryptData(currentKey, ksn, iv, ciphertext []byte, keyType, action string) (string, error)
- Utility function that used to get next key serial number
GenerateNextAesKsn(ksn []byte) ([]byte, error)
How to
First step is to derive initial key in from base derivative key and key serial number (or initial key id). Base derivative key (BKD) can get from base derivative key id. The package don't specify how to get base derivative key.
- des
ik, err := DerivationOfInitialKey(bdk, ksn)
if err != nil {
return err
}
- aes
ik, err := DerivationOfInitialKey(bdk, initialKeyID)
if err != nil {
return err
}
Second step is to generate transaction key in from generated initial key and key serial number.
transactionKey, err := DeriveCurrentTransactionKey(ik, ksn)
if err != nil {
return err
}
Data (pin, mac, normal data) is encrypted/decrypted using generated initial key and transaction key
- des
eryptedPin, err := EncryptPin(transactionKey, pin, pan, FormatVersion)
if err != nil {
return err
}
decryptedPin, err := DecryptPin(transactionKey, encryptedPin, pan, FormatVersion)
if err != nil {
return err
}
- aes
encPinblock, err := EncryptPin(transactionKey, ksn, pin, pan, KeyAES128Type)
if err != nil {
return err
}
decPinblock, err := DecryptPin(transactionKey, ksn, encPinblock, pan, KeyAES128Type)
if err != nil {
return err
}
Command lines
dukptcli is a tool for both tdes and aes derived unique key per transaction (dukpt) key management.
USAGE
dukptcli [-v] [-algorithm] [-ik] [-tk] [-ep] [-dp] [-gm] [-en] [-de]
EXAMPLES
dukptcli -v Print the version of dukptcli (Example: v1.0.0)
dukptcli -algorithm Data encryption algorithm (options: des, aes)
dukptcli -ik Derive initial key from base derivative key and key serial number (or initial key id)
dukptcli -tk Derive transaction key (current transaction key) from initial key and key serial number
dukptcli -ep Encrypt pin block using dukpt transaction key
dukptcli -dp Decrypt pin block using dukpt transaction key
dukptcli -gm Generate mac using dukpt transaction key
dukptcli -en Encrypt data using dukpt transaction key
dukptcli -de Decrypt data using dukpt transaction key
FLAGS
-algorithm string
data encryption algorithm (options: des, aes) (default "des")
-algorithm.key_type string
key type of aes (options: aes128, aes192, aes256 (default "aes128")
-de
decrypt data using dukpt transaction key
-de.action string
request or response action (default "request")
-de.data string
encrypted text transformed from plaintext using an encryption algorithm
-de.iv string
initial vector (not formatted string)
-de.ksn string
key serial number
-de.tk string
current transaction key
-dp
decrypt pin block using dukpt transaction key
-dp.format string
pin block format (ISO-0, ISO-1, ISO-2, ISO-3, ISO-4, ANSI, ECI1, ECI2, ECI3, ECI4, VISA1, VISA2, VISA3, VISA4)
-dp.ksn string
key serial number
-dp.pan string
not formatted pan string
-dp.pin string
encrypted text transformed from plaintext using an encryption algorithm
-dp.tk string
current transaction key
-en
encrypt data using dukpt transaction key
-en.action string
request or response action (default "request")
-en.data string
not formatted request data
-en.iv string
initial vector (not formatted string)
-en.ksn string
key serial number
-en.tk string
current transaction key
-ep
encrypt pin block using dukpt transaction key
-ep.format string
pin block format (ISO-0, ISO-1, ISO-2, ISO-3, ISO-4, ANSI, ECI1, ECI2, ECI3, ECI4, VISA1, VISA2, VISA3, VISA4)
-ep.ksn string
key serial number
-ep.pan string
not formatted pan string
-ep.pin string
not formatted pin string
-ep.tk string
current transaction key
-gm
generate mac using dukpt transaction key
-gm.action string
request or response action (default "request")
-gm.data string
not formatted request data
-gm.ksn string
key serial number
-gm.tk string
current transaction key
-gm.type string
cmac or hmac style (is valid using aes algorithm) (default "cmac")
-ik
derive initial key from base derivative key and key serial number (or initial key id)
-ik.bdk string
base derivative key
-ik.kid string
initial key id
-ik.ksn string
key serial number
-tk
derive transaction key (current transaction key) from initial key and key serial number
-tk.ik string
initial key
-tk.ksn string
key serial number
-v Print dupkt cli version
User should use main flag and sub flag. algorithm.key_type flag is a sub flag of algorithm flag.
There are some execution flags in this cli
dukptcli -ik Derive initial key from base derivative key and key serial number (or initial key id)
dukptcli -tk Derive transaction key (current transaction key) from initial key and key serial number
dukptcli -ep Encrypt pin block using dukpt transaction key
dukptcli -dp Decrypt pin block using dukpt transaction key
dukptcli -gm Generate mac using dukpt transaction key
dukptcli -en Encrypt data using dukpt transaction key
dukptcli -de Decrypt data using dukpt transaction key
Execution flags (ik, tk, ep, dp, gm, en, de) can use with algorithm. These flags can't run simultaneously. That is that will do a main execution only. Execution priority is ik, tk, ep, dp, gm, en, de when setting several main flags.
Example:
dukptcli -algorithm=des -gm=true -ik=true -ik.bdk=0123456789ABCDEFFEDCBA9876543210 -ik.ksn=FFFF9876543210E00001
RESULT: 6ac292faa1315b4d858ab3a3d7d5933a
In above example, the execution is to derive initial key with specified algorithm although set two execution flags
Service instance
DUKPT library provided service instance that support multi dukpt encrypt machines.
type Service interface {
CreateMachine(m *Machine) error
GetMachine(ik string) (*Machine, error)
GetMachines() []*Machine
MakeNextKSN(ik string) (*Mac

