API Encryption
This guide explains how to use encryption with the Cashonrails API to secure your payloads and responses.
Overview
Cashonrails supports AES-256 GCM encryption for both request payloads and API responses. This adds an additional layer of security for sensitive data transmission beyond standard TLS.
Headers
Use the following headers to enable encryption:
Header | Value | Description |
---|---|---|
X-Encrypted-Payload | true/false | Notify the server that you are sending an encrypted payload |
X-Encrypt-Response | true/false | Request that the server sends an encrypted response |
Encryption Process
Encrypting Request Payloads
When you want to encrypt a request payload:
- Set the
X-Encrypted-Payload: true
header - Encrypt your JSON payload using AES-256 GCM
- Send the encrypted data as your request body
Encryption Requirements
Parameter | Description |
---|---|
encryptionKey | Your Cashonrails encryption key (32 bytes) |
algorithm | AES-256-GCM |
iv | Initialization vector (16 bytes) |
aad | Additional authenticated data (optional, can be empty) |
inputFormat | JSON string of the payload |
outputFormat | Base64 encoded string of the encrypted payload |
Sample cURL Request
Here’s an example of how to make a request using cURL with encryption:
# First, encrypt your payload using one of the encryption methods shown above
# For demonstration, we'll use an already encrypted payload
# Your API key for authorization
API_KEY="sk_live_abc123def456ghi789"
# Encrypted payload (result from calling your encrypt function)
ENCRYPTED_PAYLOAD="eyJpdiI6InJUT05ZQVFOc2RiZThuS1AiLCJ2YWx1ZSI6InJjaW9MSlNidmdxRUlxc281WXpmVEtKUzdcL1BrKzFVb2pNVElmUmhQYWZ4NXZoR3h6Y1k0TlRoSit1bG9nSWZ3bXBSeGpPSDVSR0pOXC9vUXBaR0xLWDVYeng1VmVna2dua0djaG9GN1ZublBqc1c3cEh1ZUVFckFhTHlwZGxrYUJuem96SndEdTlrcGVOU3YxQzk0XC9iUStZcFlsM21Ba0Y3bWlOdTdMVVFSUmFPVXFPYkpJcEd2V2tlT2pEOGlPM1VKdnIzcFp3S2RFQUJxWWhGRTdKWG05XC9OTDBBT2RMK05QQVVQQWRyREplUStFWGZucnh0RVwvZkxkbURjOXJcL0pZZXNXU2pBRDFlOCtUK3d6ZitaS0hpSzNBNDhCIiwibWFjIjoiIiwidGFnIjoiaDdKRmgzWUE2VWFoMFhyeENhUjlUZz09In0="
# Make the API request with encrypted payload
curl -X POST "https://api.cashonrails.com/v1/transfers" \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-H "X-Encrypted-Payload: true" \
-H "X-Encrypt-Response: true" \
-d "${ENCRYPTED_PAYLOAD}"
# The response will be encrypted if X-Encrypt-Response was set to true
# You'll need to decrypt it using your decryption function
###### Sample Original Payload
```json
{
"Account_number":"0232983020",
"account_name":"Owolana Ayomide",
"bank_code":"000013",
"Amount":"100",
"currency":"NGN",
"sender_name":"John",
"narration":"John",
"reference":"VRZ-PYO-6834885B6E334-1748273243"
}
Sample Encrypted Payload
eyJpdiI6InJUT05ZQVFOc2RiZThuS1AiLCJ2YWx1ZSI6InJjaW9MSlNidmdxRUlxc281WXpmVEtKUzdcL1BrKzFVb2pNVElmUmhQYWZ4NXZoR3h6Y1k0TlRoSit1bG9nSWZ3bXBSeGpPSDVSR0pOXC9vUXBaR0xLWDVYeng1VmVna2dua0djaG9GN1ZublBqc1c3cEh1ZUVFckFhTHlwZGxrYUJuem96SndEdTlrcGVOU3YxQzk0XC9iUStZcFlsM21Ba0Y3bWlOdTdMVVFSUmFPVXFPYkpJcEd2V2tlT2pEOGlPM1VKdnIzcFp3S2RFQUJxWWhGRTdKWG05XC9OTDBBT2RMK05QQVVQQWRyREplUStFWGZucnh0RVwvZkxkbURjOXJcL0pZZXNXU2pBRDFlOCtUK3d6ZitaS0hpSzNBNDhCIiwibWFjIjoiIiwidGFnIjoiaDdKRmgzWUE2VWFoMFhyeENhUjlUZz09In0=
Decryption Process
Decrypting API Responses
When you request an encrypted response:
- Set the
X-Encrypt-Response: true
header in your request - Receive a Base64-encoded encrypted response
- Decode and decrypt the response
Encrypted Response Format
After Base64 decoding, the encrypted response will have the following structure:
{
"iv": "sO3qZVP2rsrip80l",
"value": "CNd3JPfWpuwuJ8MAzCpWTzuzZAzVy0PumIrDKFH71DmY1LbiNX2uVGQiUxA9bElA2264XYINR0PGnpQfk28Ipe/fx0zMbyzP6UeC9gC9C4qt86+3nJ+Nea0B4zGnBwBkU44SrgNZNCsEDN/8Pfeyzw0CHzdWztJ1aTduCqb1k1GRjkOacBi2C3y/3GU3wgN30BHIPvvgMn69aFMhKFw6PMSM",
"Mac": "",
"tag": "iOLEuaguzrTg0RLBfFUCDg=="
}
Sample Decrypted Response
{
"Success": false,
"Status": "03",
"message": "Transfer Failed",
"Trx": "2025052621411354625166",
"sessionId": null,
"statusMessage": "Insufficient Wallet Balance"
}
Examples of Encryption/Decryption in Different Languages
Node.js Implementation
const crypto = require('crypto');
/**
* Cashonrails encryption module for securing API payloads
* @module cashonrails-encryption
*/
/**
* Encrypt payload using AES-256-GCM
* @param {Object} plaintext - The payload to encrypt
* @param {string} encryptionKey - Your Cashonrails encryption key
* @returns {string} Base64 encoded encrypted payload
*/
function encrypt(plaintext, encryptionKey) {
const algorithm = 'aes-256-gcm';
const iv = crypto.randomBytes(16);
const key = Buffer.from(encryptionKey, 'utf8');
const cipher = crypto.createCipheriv(algorithm, key, iv);
cipher.setAAD(Buffer.alloc(0)); // Empty AAD
const serializedData = JSON.stringify(plaintext);
let encrypted = cipher.update(serializedData, 'utf8', 'base64');
encrypted += cipher.final('base64');
const tag = cipher.getAuthTag();
const encryptionObject = {
iv: iv.toString('base64'),
value: encrypted,
mac: '',
tag: tag.toString('base64')
};
return Buffer.from(JSON.stringify(encryptionObject)).toString('base64');
}
/**
* Decrypt response using AES-256-GCM
* @param {string} cipherInput - Base64 encoded encrypted response
* @param {string} encryptionKey - Your Cashonrails encryption key
* @returns {Object} Decrypted response object
*/
function decrypt(cipherInput, encryptionKey) {
const algorithm = 'aes-256-gcm';
const key = Buffer.from(encryptionKey, 'utf8');
const raw = Buffer.from(cipherInput, 'base64').toString('utf8');
const obj = JSON.parse(raw);
const iv = Buffer.from(obj.iv, 'base64');
const tag = Buffer.from(obj.tag, 'base64');
const ciphertext = obj.value;
const decipher = crypto.createDecipheriv(algorithm, key, iv);
decipher.setAAD(Buffer.alloc(0)); // Empty AAD
decipher.setAuthTag(tag);
let decrypted = decipher.update(ciphertext, 'base64', 'utf8');
decrypted += decipher.final('utf8');
return JSON.parse(decrypted);
}
// Export the functions if using as a module
module.exports = { encrypt, decrypt };
// Usage Example
const encryptionKey = 'your-encryption-key';
const payload = {
Account_number: "0232983020",
account_name: "Owolana Ayomide",
bank_code: "000013",
Amount: "100",
currency: "NGN",
sender_name: "John",
narration: "John",
reference: "VRZ-PYO-6834885B6E334-1748273243"
};
const encryptedPayload = encrypt(payload, encryptionKey);
console.log('Encrypted:', encryptedPayload);
// For decrypting responses
const decryptedResponse = decrypt(encryptedResponseFromAPI, encryptionKey);
console.log('Decrypted:', decryptedResponse);
Best Practices
- Store your encryption key securely and never expose it in client-side code
- Implement proper error handling for encryption/decryption failures
- Consider using encryption for sensitive operations like fund transfers
- Test your encryption implementation thoroughly before using in production
Security Considerations
- This encryption is in addition to, not a replacement for, HTTPS/TLS
- The security of your implementation depends on protecting your encryption key
- Properly validate all decrypted data before processing it