Card Encryption
In the financial industry, an acquiring card refers to the ability to store details of external debit cards issued by other banks. For example, Mbanq offers its end-users the convenience of storing their external debit cards in their accounts. Once stored, users can perform two main operations with the acquired debit card:
- Pull funds from the acquired debit card: Users can transfer funds from the stored debit card to their Mbanq account.
- Push funds to the acquired debit card: Users can transfer funds from their Mbanq account to the stored debit card.
**API Endpoints Referenced:
To comply with the Payment Card Industry Data Security Standard (PCI DSS), which ensures the security of cardholder data, Mbanq aims to minimize the FinTech's PCI compliance requirements. One way to achieve this is by not storing sensitive card data, such as the card number, expiry date, and CVV code. Instead, all sensitive data will be encrypted with a public key on the user's device at the time of card entry. The encrypted data will then be securely transmitted to Mbanq, where it will be tokenized. A unique token will be issued to identify the acquired card, which will be used for all subsequent activities on the card.
Encryption Standards and Requirements
To ensure strong encryption, Mbanq adopts the RSA encryption algorithm with the transformation of RSA/ECB/OAEPWithSHA-256AndMGF1Padding. This ensures the secure encryption of sensitive card data before transmission. The following requirements are important for implementing encryption:
- RSA Encryption with OAEP and SHA-256: Use the RSA algorithm with Optimal Asymmetric Encryption Padding (OAEP) and SHA-256 hash for encryption.
- Public Key: Obtain the public key required for encryption. The public key is used to encrypt the sensitive card data.
- Base64 URL-Safe Encoding: Convert the encrypted data to Base64 URL-Safe format before transmitting it to Mbanq's servers.
JavaScript Code Sample Explanation
Below is a JavaScript code sample that demonstrates how to implement the encryption of acquired card information using the RSA encryption algorithm with OAEP and SHA-256. The code utilizes various helper functions for data manipulation and encryption:
// Helper function: Convert Base64 URL-Safe to Base64 regular
function unescapeBase64(str) {
return (str + '==='.slice((str.length + 3) % 4)).replace(/-/g, '+').replace(/_/g, '/');
}
// Helper function: Convert Base64 regular to Base64 URL-Safe
function escapeBase64(str) {
return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}
// Helper function: Import RSA key from the provided keyID
function importRSAKey(keyID) {
const pemContents = unescapeBase64(keyID);
const binaryDerString = window.atob(pemContents);
const binaryDer = stringToArrayBuffer(binaryDerString);
return window.crypto.subtle.importKey("spki", binaryDer, { name: "RSA-OAEP", hash: "SHA-256" }, true, ["encrypt"]);
}
// Helper function: Convert string to ArrayBuffer
function stringToArrayBuffer(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
// Helper function: Get the string encoding for the given value
function getStringEncoding(value) {
let enc = new TextEncoder();
return enc.encode(value);
}
// Helper function: Convert ArrayBuffer to Base64 string
function arrayBufferToBase64(buffer) {
let binary = '';
const bytes = new Uint8Array(buffer);
const len = bytes.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
// Main function for encrypting card info
(function () {
// Replace 'keyID' with the actual ASN.1 Format Base64 URL-Safe public key
const keyID = 'WcCBIjAnBGkhki...';
// Replace 'cardInfo' with the actual card details in the format `${cardAccountNumber}|${cardExpirationDate format('YYYYMM')}|${cardSecurityCode}`
const cardInfo = '9010100999999995|209912|123';
// Import RSA public key and encrypt cardInfo
importRSAKey(keyID).then(RSAKey => {
let encoded = getStringEncoding(cardInfo);
window.crypto.subtle.encrypt({ name: "RSA-OAEP" }, RSAKey, encoded)
.then(data => {
// Encrypted data
const dataEncrypted = arrayBufferToBase64(data);
// Use the value returned from escapeBase64(dataEncrypted) with Tabapay
console.log(escapeBase64(dataEncrypted));
});
});
})();Table: Request Object Parameters
| Parameter | Value Type | Explanation | ||
|---|---|---|---|---|
| keyID | String | ASN.1 Format Base64 URL-Safe public key used for encryption. Obtain this from the service provider. | ||
| cardInfo | String | The sensitive card data to be encrypted in the format ${cardAccountNumber} | ${cardExpirationDate format('YYYYMM')} | ${cardSecurityCode}. Make sure to replace this with the actual card details to encrypt. |
Note: Ensure you use test card numbers while testing in the sandbox environment. Never use real card numbers in the testing phase. The provided JavaScript code is for demonstration purposes and not meant for production use.
Updated about 2 months ago
