Introduction to Sending Secure Data
Thredd enables customers to be able to send secure data to a cardholder. This is available to customers with or without PCI DSS compliance.
Important
Thredd does not authenticate the device or the identity of the device holder. We strongly recommend that you implement policy-based controls to identify cardholders.
Two keys will be provided by Thredd. You must convert them to byte arrays to use the encrypted data endpoint.
- A Thredd signature RSA key. This is not to be used for encryption.
- A customer specific RSA key. This is to be used for encryption.
Note
Thredd provide the public key as a certificate or a raw key. Contact your Implementation Manager to let them know which you would prefer.
To use the encryption endpoints, combine the customer-specific RSA key with an encrypted AES key. The AES key must first be created, then encrypted.
Creating an AES Key
When creating an AES key, ensure that the key:
- Is uniquely generated for each request.
- Has a length that is no smaller than 256 bits.
- Is encrypted with your company specific public RSA key, provided to you in Hex format by Thredd.
See the below examples on how to generate an AES key using C# and NodeJs.
using System.Security.Cryptography;
public byte[] GenerateKey()
{
var aes = Aes.Create();
aes.KeySize = 256;
aes.GenerateKey();
return aes.Key;
}
const { subtle } = require('crypto').webcrypto;
async function generateKey() {
const algoritm = { name: "AES-CBC", length: 256 };
const exportable = true;
const usage = ['encrypt', 'decrypt'];
return await subtle.generateKey(algoritm, exportable, usage);
}
The script returns an unencrypted AES Key, used to decrypt the response.
Encrypt the Key
When you have the unencrypted key, you need to encrypt it so that it can be used in the body of the Get Card Data endpoint. See the below examples on how to encrypt an AES key using C# and NodeJs.
using System.Security.Cryptography;
public string EncryptAesKey(byte[] aesKey)
{
var rsaPublicKey = Convert.FromHexString("Public RSA key as hexadecimal string goes here");
using (RSACryptoServiceProvider crypto = new RSACryptoServiceProvider())
{
crypto.ImportRSAPublicKey(rsaPublicKey, out _);
var encryptedAesKey = crypto.Encrypt(aesKey, RSAEncryptionPadding.Pkcs1);
return Convert.ToBase64String(encryptedAesKey);
}
}
const { subtle } = require('crypto').webcrypto;
async function encryptAesKey(aesKey) {
let rawRsaPublicKey = Buffer.from("Public RSA key as hexadecimal string goes here", 'hex');
const format = "raw";
const rsaParams = new RSAHashedImportParams {
name = "RSASSA-PKCS1-v1_5",
hash = "SHA-256"
}
const exportable = false;
const usage = ["wrapKey"];
let rsaPublicKey = await subtle.ImportKey(format, rawRsaPublicKey, rsaParams, exportable, usage);
let wrappedKey = await subtle.wrapKey(format, aesKey, rsaPublicKey, { name: "RSA-OAEP" });
return wrappedKey.toString('base64');
}
The script returns an encrypted AES Key, use to populate the body of the Get Card Data endpoint.
Important
If you do not have PCI DSS certification, all key generation encryption, and decryption must happen on the device. You must send only encrypted data to your backend systems. Thredd is only responsible for ensuring the data is encrypted as it leaves our estate. Thredd clients are responsible for ensuring they are not breaching PCI DSS rule.
Updated 15 days ago