Encryption
When charging a card directly through our collection API, you must first encrypt the payload including the card details.
To manually encrypt the payload, you will need your encryption key (found in the Settings > API Keys & Webhooks section of your dashboard side menu). You will encrypt the payload using the 3DES technique.
Here's an illustration of an encryption function in various languages. In each example, the function takes the payload as a hash and converts it to JSON before encrypting and encoding it in base64.
const forge = require('node-forge');
const { DOMParser } = require('xmldom');
const BigInteger = forge.jsbn.BigInteger;
/**
* Encrypt data using RSA public key.
*
* @param {string} data - The data to encrypt.
* @param {string} rsaPubKey - The RSA public key in base64 XML format.
* @returns {string} - The encrypted data in base64 encoding.
*/
function encryptForge(data, rsaPubKey) {
// Decode the base64 encoded public key and remove the prefix
let rsaKeyValue = Buffer.from(rsaPubKey, 'base64').toString('utf-8');
rsaKeyValue = rsaKeyValue.replace('4096!', '');
// Parse the XML to extract Modulus and Exponent
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(rsaKeyValue, 'text/xml');
const modulus = xmlDoc.getElementsByTagName('Modulus')[0].textContent;
const exponent = xmlDoc.getElementsByTagName('Exponent')[0].textContent;
// Convert the Modulus and Exponent from base64 to BigInteger
const modulusBI = parseBigInteger(modulus);
const exponentBI = parseBigInteger(exponent);
// Set up the RSA public key
const pubKey = forge.pki.setRsaPublicKey(modulusBI, exponentBI);
// Encrypt the data
const encryptedBytes = pubKey.encrypt(forge.util.encodeUtf8(data));
// Return the encrypted text in base64 encoding
return Buffer.from(encryptedBytes, 'binary').toString('base64');
}
/**
* Convert a base64 encoded string to a BigInteger.
*
* @param {string} b64 - The base64 encoded string.
* @returns {BigInteger} - The BigInteger representation of the string.
*/
function parseBigInteger(b64) {
const decoded = forge.util.decode64(b64);
return new BigInteger(forge.util.createBuffer(decoded).toHex(), 16);
}
// Example usage
const data = "Your data to encrypt";
const rsaPubKey = "Your RSA public key in base64 XML format";
const encryptedData = encryptForge(data, rsaPubKey);
console.log(encryptedData);
module.exports = encryptForge;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.crypto.Cipher;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
//import javax.xml.bind.DatatypeConverter;
public class EncryptionHelper {
private PrivateKey privateKey;
private PublicKey publicKey;
public static String getXmlComponent(String xmlstring, String _field) throws IOException, SAXException, ParserConfigurationException {
// Create a DocumentBuilder
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
// Parse the XML string
Document doc = dBuilder.parse(new java.io.ByteArrayInputStream(xmlstring.getBytes("UTF-8")));
// Normalize the document
doc.getDocumentElement().normalize();
NodeList modulusNodeList = doc.getElementsByTagName(_field);
String modulusValue = "";
if (modulusNodeList.getLength() > 0) {
Element modulusElement = (Element) modulusNodeList.item(0);
// Extract the Modulus value
modulusValue = modulusElement.getTextContent();
System.out.println("Modulus Value: " + modulusValue);
} else {
System.out.println("Modulus element not found.");
}
return modulusValue;
}
public static byte[] encrypt(String _data, String publicXml) throws Exception {
try {
var data = _data.getBytes();
if (data == null || data.length < 1) {
throw new Exception("Data sent for encryption is empty");
}
// Extract the Modulus and Exponent from the XML
// Decode the Base64 string
byte[] decodedBytes = Base64.getDecoder().decode(publicXml);
// Convert the decoded bytes to a string
String decodedString = new String(decodedBytes);
var publicxmllkey = decodedString.split("!")[1];
System.out.println(publicxmllkey);
var modulus = getXmlComponent(publicxmllkey, "Modulus");
var exponent = getXmlComponent(publicxmllkey, "Exponent");
String modulusBase64 = modulus;
String exponentBase64 = exponent/* extract Exponent from publicXml */;
// Convert the Base64-encoded Modulus and Exponent to byte arrays
byte[] modulusBytes = Base64.getDecoder().decode(modulusBase64);
byte[] exponentBytes =Base64.getDecoder().decode(exponentBase64);
// Create RSAPublicKeySpec from Modulus and Exponent
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(
new java.math.BigInteger(1, modulusBytes),
new java.math.BigInteger(1, exponentBytes)
);
// Generate the PublicKey from the RSAPublicKeySpec
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
// Initialize the Cipher for encryption
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// Encrypt the data
byte[] encryptedBytes = cipher.doFinal(data);
return encryptedBytes;
} catch (Exception e) {
throw e;
}
}
public EncryptionHelper() throws Exception {
var rowdata = "Hello World";
var publicxml = "NDA5NiE8UlNBS2V5VmFsdWU+PE1vZHVsdXM+eTJTSXdvQTY4cmNwZlNYcjJwbWhUYmp3NzRLOEgwTW5CN2NhbWNSVStlMVZmZ3o3d2xISysvYi9kdE9NLzVtYVBZV1l0aW1YcURoNlppTHZyUytqaklhVkhjS2trS3dscTNrK1BTSDR1ckpqeElOQSt4RHBQSW1aWFVLMjJobmp2c2s1YTM2Vkx2Q1NPd2IwTXJXaHJwaXNKem9sS3VEaFR1MjhnYWNsT1FaR2JoNStNazdyV0ZnVjVLZThqcUFZK1FIMk16RmZYNys3ZldKbXhGQTlReEI5SThTODhBMC9SWm5SNUlJQWtrRHh3aGtsSlB0NEtQeG5GT0RmTHQyR3Z0YXp3NmlTNmNUUlBHVkF5MmNocDRrZmZSVFcrd0FhaTlycTV5V2h0cHFaOVlCZ1N1MUFLd2twd01NL3o0cVJHWDJOdWZoOEtnMWV6cUs0WkVnTGhOYnN1aXZ5NmdZNEZxMjdSZWpndDN1S0hmdmExaUtYLysxVVI5cmlIMjJYUVZEMzFIamFieUJoZ2lTcVBIMzgwUVBNMnlpdnpKZDdyWDZqMEpzZk1NRFlGejJzMCtIUHJoQmd6cFBua3l2S0RGMUFZcjRTc2RQaitCNUxrYlZESUg4TC9zZE1DcEpyblJqMWlHRXgvWUl4U1ExdEJFZWFnbWFxVVF2VVJYV2hOeHNIS0Nxa3Buelh3bVdpT3FUR1RNRWdpc2UvbkI3SHVuVlRITEZ0d0UyVE1LYXZxbEFkUHNxMytlSFNqUzhQVmZNK1IxL1VoMUVTR09aOFZZdThTMjdFYWl6dDY4SmhVbDQ0NnVjT0R4VEJTckFYS0ptdGhjZk9MZzNYekU5TVlkaEZiWisxRzlHbi91YkVFd2ZiZVZsOVViVXZ6WDEwZmxTZXRlUnZ0ZDg9PC9Nb2R1bHVzPjxFeHBvbmVudD5BUUFCPC9FeHBvbmVudD48L1JTQUtleVZhbHVlPg==";
var result = encrypt(rowdata, publicxml);
// Encode the byte array to a Base64 string
String base64String = Base64.getEncoder().encodeToString(result);
System.out.println("Converted successfully");
System.out.println(base64String);
}
public static void main(String[] args) throws Exception {
EncryptionHelper keyPairGenerator = new EncryptionHelper();
}
}
<?php
// Include the phpseclib library for RSA encryption
require 'vendor/autoload.php';
use phpseclib3\Crypt\RSA;
use phpseclib3\Math\BigInteger;
/**
* Encrypt data using RSA public key.
*
* @param string $data The data to encrypt.
* @param string $rsa_pub_key The RSA public key in XML format.
* @return string The encrypted data in base64 encoding.
*/
function encryptForge($data, $rsa_pub_key) {
// Decode the base64 encoded public key and remove the prefix
$rsaKeyValue = base64_decode($rsa_pub_key);
$rsaKeyValue = str_replace('4096!', '', $rsaKeyValue);
// Load the XML document
$xmlDoc = new DOMDocument();
$xmlDoc->loadXML($rsaKeyValue);
// Extract the Modulus and Exponent values from the XML
$modulus = $xmlDoc->getElementsByTagName('Modulus')[0]->nodeValue;
$exponent = $xmlDoc->getElementsByTagName('Exponent')[0]->nodeValue;
// Convert the Modulus and Exponent from base64 to BigInteger
$modulusBI = parseBigInteger($modulus);
$exponentBI = parseBigInteger($exponent);
// Set up the RSA public key
$rsa = RSA::loadPublicKey([
'n' => $modulusBI,
'e' => $exponentBI,
]);
// Encrypt the data
$encryptText = $rsa->encrypt($data);
// Return the encrypted text in base64 encoding
return base64_encode($encryptText);
}
/**
* Convert a base64 encoded string to a BigInteger.
*
* @param string $b64 The base64 encoded string.
* @return BigInteger The BigInteger representation of the string.
*/
function parseBigInteger($b64) {
$decoded = base64_decode($b64);
return new BigInteger(bin2hex($decoded), 16);
}
// Example usage
$data = "Your data to encrypt";
$rsa_pub_key = "Your RSA public key in base64 XML format";
$encryptedData = encryptForge($data, $rsa_pub_key);
echo $encryptedData;
?>
import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Util.Padding import pad
import xml.etree.ElementTree as ET
def encrypt(data, public_xml):
try:
if not data:
raise Exception("Data sent for encryption is empty")
print(data)
# Decode the Base64 string
decoded_bytes = base64.b64decode(public_xml)
# Convert the decoded bytes to a string
decoded_string = decoded_bytes.decode('utf-8')
public_xml_key = decoded_string.split('!')[1]
modulus = getXmlComponent(public_xml_key, "Modulus")
exponent = getXmlComponent(public_xml_key, "Exponent")
modulus_bytes = base64.b64decode(modulus)
exponent_bytes = base64.b64decode(exponent)
# Create an RSA public key from Modulus and Exponent
key = RSA.construct((int.from_bytes(modulus_bytes, byteorder='big'), int.from_bytes(exponent_bytes, byteorder='big')))
# Initialize the Cipher for encryption
cipher = PKCS1_v1_5.new(key)
# Encrypt data
encrypted_bytes = cipher.encrypt(bytes(data, 'utf-8'))
print(encrypted_bytes)
#Convert to base 64 string
encrypted_bytes_ = base64.b64encode(encrypted_bytes)
print(encrypted_bytes_)
return encrypted_bytes
except Exception as e:
raise e
def getXmlComponent(xmlstring, _field):
try:
# Parse the XML string
root = ET.fromstring(xmlstring)
# Find elements with the specified field name
modulusElements = root.findall(_field)
modulusValue = ""
if modulusElements:
# Extract the Modulus value from the first element
modulusValue = modulusElements[0].text
print("Modulus Value:", modulusValue)
else:
print("Modulus element not found.")
return modulusValue
except Exception as e:
# Handle exceptions (e.g., parsing errors)
print("Error:", str(e))
return ""
# Example usage:
_data = "{\"order\":{}}"
public_xml = "NDA5NiE8UlNBS2V5VmFsdWU+PE1vZHVsdXM+eTJTSXdvQTY4cmNwZlNYcjJwbWhUYmp3NzRLOEgwTW5CN2NhbWNSVStlMVZmZ3o3d2xISysvYi9kdE9NLzVtYVBZV1l0aW1YcURoNlppTHZyUytqaklhVkhjS2trS3dscTNrK1BTSDR1ckpqeElOQSt4RHBQSW1aWFVLMjJobmp2c2s1YTM2Vkx2Q1NPd2IwTXJXaHJwaXNKem9sS3VEaFR1MjhnYWNsT1FaR2JoNStNazdyV0ZnVjVLZThqcUFZK1FIMk16RmZYNys3ZldKbXhGQTlReEI5SThTODhBMC9SWm5SNUlJQWtrRHh3aGtsSlB0NEtQeG5GT0RmTHQyR3Z0YXp3NmlTNmNUUlBHVkF5MmNocDRrZmZSVFcrd0FhaTlycTV5V2h0cHFaOVlCZ1N1MUFLd2twd01NL3o0cVJHWDJOdWZoOEtnMWV6cUs0WkVnTGhOYnN1aXZ5NmdZNEZxMjdSZWpndDN1S0hmdmExaUtYLysxVVI5cmlIMjJYUVZEMzFIamFieUJoZ2lTcVBIMzgwUVBNMnlpdnpKZDdyWDZqMEpzZk1NRFlGejJzMCtIUHJoQmd6cFBua3l2S0RGMUFZcjRTc2RQaitCNUxrYlZESUg4TC9zZE1DcEpyblJqMWlHRXgvWUl4U1ExdEJFZWFnbWFxVVF2VVJYV2hOeHNIS0Nxa3Buelh3bVdpT3FUR1RNRWdpc2UvbkI3SHVuVlRITEZ0d0UyVE1LYXZxbEFkUHNxMytlSFNqUzhQVmZNK1IxL1VoMUVTR09aOFZZdThTMjdFYWl6dDY4SmhVbDQ0NnVjT0R4VEJTckFYS0ptdGhjZk9MZzNYekU5TVlkaEZiWisxRzlHbi91YkVFd2ZiZVZsOVViVXZ6WDEwZmxTZXRlUnZ0ZDg9PC9Nb2R1bHVzPjxFeHBvbmVudD5BUUFCPC9FeHBvbmVudD48L1JTQUtleVZhbHVlPg=="
encrypted_data = encrypt(_data, public_xml)
Updated 5 months ago