Skip to content

Encryption & Decryption

This guide explains how to encrypt responses and decrypt incoming webhook requests using AES-256-ECB encryption.

  • Algorithm: AES (Advanced Encryption Standard)
  • Key Size: 256 bits
  • Mode: ECB (Electronic Codebook)
  • Padding: PKCS#7 (also known as PKCS5)
  • Encryption Key: Your API Key

When you receive a webhook request, follow this flow:

import crypto from 'crypto';
function decrypt(encryptedData, apiKey) {
// Create decipher with AES-256-ECB
const decipher = crypto.createDecipheriv(
'aes-256-ecb',
Buffer.from(apiKey, 'utf8'),
null // ECB mode doesn't use IV
);
// Disable automatic padding
decipher.setAutoPadding(true);
// Decrypt the data
let decrypted = decipher.update(encryptedData, 'base64', 'utf8');
decrypted += decipher.final('utf8');
return JSON.parse(decrypted);
}
// Usage
app.post('/webhook', express.text(), (req, res) => {
const encryptedBody = req.body;
const decryptedData = decrypt(encryptedBody, API_KEY);
console.log(decryptedData);
/*
{
"transaction_id": "2_sandboxagent01_1763107598923_1922",
"event_type": "bet",
"timestamp": 1763107599,
"feedback_data": "TEST_FEEDBACK_DATA",
"user_id": "edwincalma",
"data": {
"currency": "KRW",
"game_type": "BAC",
"table_no": "DH002",
"game_no": "DH0022511141328",
"total_bet_amount": 5000,
"bets": [
{
"bet_index": "10404",
"bet_type": "P",
"bet_amount": 5000
}
]
}
}
*/
});

When sending a response, follow this flow:

function encrypt(data, apiKey) {
// Create cipher with AES-256-ECB
const cipher = crypto.createCipheriv(
'aes-256-ecb',
Buffer.from(apiKey, 'utf8'),
null // ECB mode doesn't use IV
);
// Enable automatic padding
cipher.setAutoPadding(true);
// Convert data to JSON string
const jsonString = JSON.stringify(data);
// Encrypt the data
let encrypted = cipher.update(jsonString, 'utf8', 'base64');
encrypted += cipher.final('base64');
return encrypted;
}
// Usage
const responseData = {
result_code: 0,
response_data: {
balance: 10000
}
};
const encryptedResponse = encrypt(responseData, API_KEY);
res.status(200).send(encryptedResponse);

Here’s a complete example combining both decryption and encryption:

import express from 'express';
import crypto from 'crypto';
const app = express();
const API_KEY = 'your-32-character-api-key-here';
// Helper functions
function decrypt(encryptedData, apiKey) {
const decipher = crypto.createDecipheriv(
'aes-256-ecb',
Buffer.from(apiKey, 'utf8'),
null
);
decipher.setAutoPadding(true);
let decrypted = decipher.update(encryptedData, 'base64', 'utf8');
decrypted += decipher.final('utf8');
return JSON.parse(decrypted);
}
function encrypt(data, apiKey) {
const cipher = crypto.createCipheriv(
'aes-256-ecb',
Buffer.from(apiKey, 'utf8'),
null
);
cipher.setAutoPadding(true);
const jsonString = JSON.stringify(data);
let encrypted = cipher.update(jsonString, 'utf8', 'base64');
encrypted += cipher.final('base64');
return encrypted;
}
// Webhook endpoint
app.post('/webhook', express.text(), (req, res) => {
try {
// Decrypt incoming request
const payload = decrypt(req.body, API_KEY);
console.log('Received:', payload);
// Process based on command type
let responseData;
switch (payload.command) {
case 'login':
// Validate user and return balance
responseData = {
"code": "R0", // Required, String
"event_type": "login", // Required, String
"timestamp": 1763107693, // Required, Number
"user_id": "edwincalma", // Required, String
"latest_balance": 1111000 // Required, Number
};
break;
case 'bet':
// Deduct bet amount
const betAmount = payload.data.bet_gold;
responseData = {
"code": "R0", // Required, String
"event_type": "bet", // Required, String
"timestamp": 1763107509, // Required, Number
"user_id": "edwincalma", // Required, String
"latest_balance": 1000000 // REQUIRED, Number
};
break;
// Handle other commands...
}
// Encrypt and send response
const encryptedResponse = encrypt(responseData, API_KEY);
res.status(200).send(encryptedResponse);
} catch (error) {
console.error('Error processing webhook:', error);
// Even on error, send encrypted response
const errorResponse = {
result_code: 1,
response_data: {
message: 'Internal server error'
}
};
const encryptedError = encrypt(errorResponse, API_KEY);
res.status(200).send(encryptedError);
}
});
app.listen(3000, () => {
console.log('Webhook server running on port 3000');
});

Solution: Ensure setAutoPadding(true) is called on both cipher and decipher.

Solution: Verify your API Key is exactly 32 characters.

Solution: Check that you’re using the correct encoding (base64 for encrypted, utf8 for decrypted).