DCM platform utilizes the public keys of participating banks to encrypt data during the formation of payment messages. In plaintext, the data is only accessible to the banks involved in the operation.
DCM platform does not have access to open customer data and tools to decrypt it.
A comprehensive codebase has been developed to fully support the functionality of encoding and decoding personal data.
Go examples:
PHP examples:
Java examples:
Python examples:
The following process is built on this foundation
Public Key Transmission
Each participant of the DCM platform generates and places their public key.
This key is used to authorize requests and encrypt data, which can only be decrypted by the recipient bank using its private key.
Order Initiation
The merchant sends transaction details and their servicing bank to the DCM platform. Based on the received information, the DCM platform forms the order.
Payment Details Transmission
Payment details are available through:
QR Code: Accessed via a GET /merchants/order/nbu/json request.
Deep-link: Payment details provided in JWT format.
Encoding Personal Data by the Initiator Bank
a.AES-256 Key Generation:
A random symmetric key is created for each payment message.
Example code in the Go programming language
func NewAES256RandomKey(rnd *rand.Rand) ([]byte, error) {
key := make([]byte, 32) // Allocate 32 bytes for the AES-256 key
_, err := rnd.Read(key) // Fill the slice with random data
if err != nil {
return nil, err // Return error if reading failed
}
return key, nil // Return the random AES key
b. AES-GCM Encryption Mode and Algorithm Setup:
This mode ensures both encryption and authentication of data.
Example code in the Go programming language
// generate random AES-256 key
aesKey, err := NewAES256RandomKey(rnd)
if err != nil {
return result, err
}
block, err := aes.NewCipher(aesKey)
if err != nil {
return result, err
}
// initialize the Galois/Counter Mode (GCM) cipher
crypter, err := cipher.NewGCM(block)
if err != nil {
return result, err
}
c. Nonce (Salt) Generation:
Random data is generated to ensure encryption uniqueness.
Example code in the Go programming language
// generate random AES-256 key
aesKey, err := NewAES256RandomKey(rnd)
if err != nil {
return result, err
}
block, err := aes.NewCipher(aesKey)
if err != nil {
return result, err
}
// initialize the Galois/Counter Mode (GCM) cipher
crypter, err := cipher.NewGCM(block)
if err != nil {
return result, err
}
d. Key Encoding:
The AES-256 key is encrypted using the recipient bank's public key, obtained via GET /merchants/order/nbu/json or deep-link.
Example code in the Go programming language
encryptedAESKey, err := rsa.EncryptOAEP(sha256.New(), crand.Reader, publicKey, aesKey, nil)
e. Encoding Personal Data:
Fields like debtor_name, debtor_id, creditor_name, and creditor_id are encoded using AES-GCM encryption and the generated nonce.
Example code in the Go programming language
// generate random AES-256 key
aesKey, err := NewAES256RandomKey(rnd)
if err != nil {
return result, err
}
block, err := aes.NewCipher(aesKey)
if err != nil {
return result, err
}
// initialize the Galois/Counter Mode (GCM) cipher
crypter, err := cipher.NewGCM(block)
if err != nil {
return result, err
}
f. Data Transmission:
Encoded personal data, the encrypted AES-256 key, and the nonce are transformed into Base64 format and included in the payment message.
Example code in the Go programming language
encryptedDebtorIDBase64 := base64.StdEncoding.EncodeToString(encryptedDebtorID)
encryptedDebtorNameBase64 := base64.StdEncoding.EncodeToString(encryptedDebtorName)
encryptedKeyBase64 := base64.StdEncoding.EncodeToString(encryptedAESKey)
nonceBase64 := base64.StdEncoding.EncodeToString(nonce)
Reading Encoded Data
а. Processing and Dispatch:
b. Decoding Steps
The recipient bank shall:
Decode the Base64 data from step 4f of the previous section.
Example code in the Go programming language
// decode base64 strings
encryptedAESKey, err := base64.StdEncoding.DecodeString(pm.EncryptedKey)
if err != nil {
return result, err
}
nonce, err := base64.StdEncoding.DecodeString(pm.Nonce)
if err != nil {
return result, err
}
encryptedDebtorID, err := base64.StdEncoding.DecodeString(result.PayloadISO.Debtor.DebtorID)
if err != nil {
return result, err
}
encryptedDebtorName, err := base64.StdEncoding.DecodeString(result.PayloadISO.Debtor.DebtorName)
if err != nil {
return result, err
}
Decrypt the AES-256 key (step 4d).
Example code in the Go programming language
// decrypt AES-256 key
hash := sha256.New()
aesKey, err := rsa.DecryptOAEP(hash, crand.Reader, privateKey, encryptedAESKey, nil)
if err != nil {
return result, err
}
Set up the AES-GCM encryption mode and algorithm.
Example code in the Go programming language
block, err := aes.NewCipher(aesKey)
if err != nil {
return result, err
}
crypter, err := cipher.NewGCM(block)
if err != nil {
return result, err
}
Using the nonce and the AES-256 key, perform the final decryption of personal data.Приклад коду на мові програмування Go
Example code in the Go programming language
debtorID, err := crypter.Open(nil, nonce, encryptedDebtorID, nil)
if err != nil {
return result, err
}
debtorName, err := crypter.Open(nil, nonce, encryptedDebtorName, nil)
if err != nil {
return result, err
}
The payment message formed and sent by the initiator bank is processed by the DCM platform, which then sends a to the recipient bank.