Encryption

Secure your payment requests with Encryption

Alliance Pay uses RSA Encryption to protect sensitive information in your requests. Using your Encryption key, We are able to encrypt and decrypt your requests making your server communication secure.

Here is sample data before and after encryption:

//sample Unencrypted create order request
{
    "customer": {
        "first_name": "Test",
        "last_name": "User",
        "mobile": "08109000001",
        "country": "NG",
        "email": "[email protected]"
    },
    "order": {
        "amount": 100,
        "reference": "test_transaction_12x",
        "description": "Test Pay",
        "currency": "NGN"
    }
}
//sample Encrypted create order request
{
    "data": "ASUkm/rG8xJ2mcjqqADBuatLG3oI6lCWWhNS782U8okDjdAtIC4w6qTyG7Bj2ohOm3CquEkWrfVIgxhpbDia6p3IiPOqiVbRrjFM+vyVYPvSsWJm8BS5/bZWlJcUIILQwehlSJnCE8z2zz+nKLG/5faPGEI4XI3X3QICZbB+XdJcyI7Hcrt3m/LzFlz3YmqZJboLI+55fwbB4kS3aetMNm4H+RNumFBrMM3WsDbY5YPofqI/VphuqCL1APqllCPTevFsVi62GA5l3GKZ7gNOTW47FMQthatrhvxijxDwc8aluRieUIdS+Zk8KE0m9yMCE/w/XLitCikxRwmyyE6Wq//flvcYZiShyWOHfZbP5uda2LBZd6dfGNz6SWmd7SzJuwqaOdVRO/7Ax010U6uUWgM1JRySqsppq5qI3fM+VWG6o34Vrg5ZZSE6pNEw1uNd5ORf9kD5tDYlnjv3FkM5fVWNH2NsBR2cRzM6HZ1o05qDirn3DvtcgBT9LB0iFOn2iFespptjU1k8AhFG4VJeFfWyuaAu7pdDHJP9HG1Jrt08FKWaFpCdgNxP6YZCOA5dIsQRsvnekq/GmF6dJmAkxm5W8P9hqlO7SapjasL25mwZmVXG/UEvhF4pb4VrViDgqJtrvBVKQZUrVWFhXb0oR0Q0FTqDOU/xex8otNpOpRU=",
    "message": "This endpoint is not available on production. It's available on staging for quick testing purposes"
}

Encrypting your Requests

There are a number of ways to encrypt your request using RSA encryption. Here are samples to help you to encrypt your request:

# include imports
import base64
import json
import os
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from dotenv import load_dotenv
import xml.etree.ElementTree as ET

# Load environment variables. We encourage you to store your keys as environment variables.
load_dotenv()

# Extract XML Components from Keys
def get_xml_component(xmlstring, _field):
    try:
        modulus_value = ET.fromstring(xmlstring).findtext(_field) or ""
        return modulus_value
    except Exception as e:
        print(f"Error: {e}")
        return ""
      
# Encrypt request using your Encryption Key
def encrypt(data, encryptionKey):
  
  # Check if a request to be encrypted is passed.
    try:
        if not data:
            raise Exception("Data sent for encryption is empty")
            

        # Extract XML Components from KeysExtract 
        decoded_string = base64.b64decode(encryptionKey).decode('utf-8').split('!')[1]
        modulus = get_xml_component(decoded_string, "Modulus")
        exponent = get_xml_component(decoded_string, "Exponent")

        key = RSA.construct((int.from_bytes(base64.b64decode(modulus), 'big'),
                             int.from_bytes(base64.b64decode(exponent), 'big')))
        
        # Generate Cipher and encrypt requests
        cipher = PKCS1_v1_5.new(key)
        encrypted_bytes = base64.b64encode(cipher.encrypt(data.encode('utf-8'))).decode('utf-8')
        print(encrypted_bytes)
        return encrypted_bytes

    except Exception as e:
        raise e
        
        
        
# "-----BEGIN USAGE-----"

# Example request
requestData = {
   "customer":{
      "first_name":"Example",
      "last_name":"User",
      "mobile":"+2348101234544",
      "country":"NG",
      "email":"[email protected]"
   },
   "order":{
      "amount":100,
      "reference":"Test-Reference-12x",
      "description":"Test Payment",
      "currency":"NGN"
   }
}

encryptedData = encrypt(json.dumps(requestData), os.getenv("ENCRYPTION_KEY"))

const forge = require('node-forge');
const NodeRSA = require('node-rsa');
const {DOMParser} = require('xmldom');

function encrypt(message, merchantEncryptionKey) {
    const encPemKey = getRsaEncryptionKey(merchantEncryptionKey);

    console.log(encPemKey);

    const encryptKey = new NodeRSA(encPemKey);
    encryptKey.setOptions({
        encryptionScheme: 'pkcs1'
    });


    const encryptedMessage = encryptKey.encrypt(message, 'base64');

    if (encryptedMessage) {
        console.log('Encrypted Message:', encryptedMessage);
    } else {
        console.error('Encryption failed.');
    }
    return encryptedMessage;
}

function getRsaEncryptionKey(merchantEncryptionKey) {
    // Decode the Base64 string
    const decodedKey = Buffer.from(merchantEncryptionKey, 'base64').toString('utf-8').split('!');
    console.log(decodedKey);

    const rsaXml = decodedKey[1];
    console.log(rsaXml);

    return xmlToPem(rsaXml);
}

function xmlToPem(xmlKey) {
    const parser = new DOMParser();
    const xmlDoc = parser.parseFromString(xmlKey, 'text/xml');

    // Extract Modulus and Exponent
    const modulusBase64 = xmlDoc.getElementsByTagName('Modulus')[0].textContent;
    const exponentBase64 = xmlDoc.getElementsByTagName('Exponent')[0].textContent;

    console.log('modulusBase64:', modulusBase64);
    console.log('exponentBase64:', exponentBase64);

    const BigInteger = forge.jsbn.BigInteger;

    function parseBigInteger(b64) {
        return new BigInteger(forge.util.createBuffer(forge.util.decode64(b64)).toHex(), 16);
    }

    const publicKey = forge.pki.setRsaPublicKey(
        parseBigInteger(modulusBase64),
        parseBigInteger(exponentBase64)
    );

    // Convert a Forge public key to PEM-format
    const pem = forge.pki.publicKeyToPem(publicKey);

    return pem;
}

module.exports = encrypt;

What’s Next