Encryption
This guide provides detailed instructions on how to send and receive data securely using encryption keys.
Encryption Overview
We prioritize the security of your data. To ensure this, we employ encryption for the data transmitted through our Public API and Webhooks.
Available Encryption Methods
An encryption method and keys are provided on the "Application" page of your account. These method and keys are essential for encrypting and decrypting data exchanged between your application and our services.
aes-256-cbc
Keys Required:
Secret Key: Used for encrypting and decrypting your JSON payload.
HMAC Key: Used to generate a signature that verifies the integrity and authenticity of your data
Header Requirement:
The HMAC signature must be included in the request headers x-allpass-signature
aes-256-gcm
Keys Required:
Secret Key: Used for encrypting and decrypting your JSON payload.
Header Requirement:
Although this method doesn’t require an additional HMAC key, the authentication tag (auth tag) generated during encryption must be provided in the headers x-allpass-signature
Sending Data to Our Public API
You have the option to send data to our Public API either encrypted or unencrypted, depending on your preference and security requirements.
Encrypted Data: To send encrypted data, use the encryption keys provided on the "Application" page. Encrypt your data before sending it to our API.The encrypted data should be included in the payload as follows:
{
"data": "encryptedString"
}
Unencrypted Data: If you prefer, you can also send data without encryption. This option is available for clients who may not require the added security layer.
Receiving Data from Public API and Webhooks
All data sent to you via our Public API or Webhooks is encrypted using the same encryption keys found on the "Application" page. Ensure you decrypt the incoming data using this key to access the information.
Steps for Integration
Retrieve Your Keys:
Log in to your account and navigate to the "Application" page.
For aes-256-cbc, retrieve both your Secret Key and your HMAC Key.
For aes-256-gcm, retrieve your Secret Key.
Encrypt Your Data:
For aes-256-cbc:
Encrypt your JSON payload using the Secret Key.
Generate an HMAC signature using your HMAC Key.
For aes-256-gcm:
Encrypt your JSON payload using the Secret Key.
Extract the authentication tag (auth tag) during encryption.
Send Data to Public API:
Payload Format:
Encrypted: Send your encrypted data to our Public API endpoint.
Headers:
For aes-256-cbc: Attach the HMAC signature, e.g.,
x-allpass-signature: yourHMACvalue
.For aes-256-gcm: Attach the authentication tag, e.g.,
x-allpass-signature: yourAuthTagValue
.
{
"data": "encryptedString"
}
Receive and Decrypt Data:
Use your Secret Key to decrypt the incoming payload.
For aes-256-cbc: Validate the HMAC signature from the headers using your HMAC Key.
For aes-256-gcm: Use the auth tag provided in the headers to ensure correct decryption and data integrity.
Example Code Snippets
Here are some example code snippets to help you get started with encryption and decryption using your key:
Encrypting Data:
aes-256-cbc :
const crypto = require('crypto');
const secretKey = 'your-encryption-key';
const hmacKey = 'your-hmac-key';
const algorithm = 'aes-256-cbc';
function encrypt(text) {
const keyBuff = Buffer.from(secretKey, 'hex');
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, keyBuff, iv);
let encrypted = cipher.update(data, 'utf8', 'hex');
encrypted += cipher.final('hex');
const payload = iv.toString('hex') + encrypted;
const hmacKeyBuff = Buffer.from(hmacKey, 'hex');
const hmac = crypto.createHmac('sha256', hmacKeyBuff);
hmac.update(payload);
const hmacDigest = hmac.digest('hex');
return {
payload,
signature: hmacDigest,
};
}
const data = JSON.stringify({ key: 'value' });
const { payload, signature } = encrypt(data);
const request = { data: encryptedData };
console.log(request);
aes-256-gcm
const crypto = require('crypto');
const key = 'your-encryption-key';
const algorithm = 'aes-256-gcm';
function encrypt(text) {
const keyBuff = Buffer.from(key, 'hex');
const iv = crypto.randomBytes(12);
const cipher = crypto.createCipheriv(algorithm, keyBuff, iv);
const encrypted = Buffer.concat([
cipher.update(data, 'utf8'),
cipher.final(),
]);
const authTag = cipher.getAuthTag();
return {
payload: iv.toString('hex') + encrypted.toString('hex'),
signature: authTag.toString('hex'),
};
}
const data = JSON.stringify({ key: 'value' });
const { payload, signature } = encrypt(data);
const request = { data: encryptedData };
console.log(request);
Decrypting Data:
aes-256-cbc:
const crypto = require('crypto');
function decryptData(
encryptedTextWithIv: string,
secretKey: string,
hmacKey: string,
signature: string
): string {
const hmacKeyBuff = Buffer.from(hmacKey, 'hex');
const hmac = crypto.createHmac('sha256', hmacKeyBuff);
hmac.update(encryptedTextWithIv);
const computedSignature = hmac.digest('hex');
if (computedSignature !== signature) {
throw new Error('Invalid signature');
}
const keyBuff = Buffer.from(secretKey, 'hex');
const iv = Buffer.from(encryptedTextWithIv.slice(0, 32), 'hex');
const encryptedText = encryptedTextWithIv.slice(32);
const decipher = crypto.createDecipheriv('aes-256-cbc', keyBuff, iv);
let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
const secretKey= `*************`; // Your crypt key from application page
const hmacKey = `*************`; // Your hmac key from application page
const signature = response.headers['x-allpass-signature']
const encryptedDataString = '... Encrypted data in Base64 ...';
const decryptedDataString = decryptData( encryptedDataString,
secretKey,
hmacKey,
signature
);
console.log('Decrypted data object:', JSON.parse(decryptedDataString));
aes-256-gcm:
const crypto = require('crypto');
function decryptData(
encryptedTextWithIv: string,
secretKey: string,
signature: string
): string {
const iv = Buffer.from(encryptedTextWithIv.slice(0, 24), 'hex');
const encryptedData = encryptedTextWithIv.slice(24);
const decipher = crypto.createDecipheriv(
'aes-256-gcm',
Buffer.from(secretKey, 'hex'),
iv,
);
decipher.setAuthTag(Buffer.from(signature, 'hex'));
const decrypted = Buffer.concat([
decipher.update(Buffer.from(encryptedData, 'hex')),
decipher.final(),
]);
return decrypted.toString('utf8');
}
const secretKey= `*************`; // Your crypt key from application page
const signature = response.headers['x-allpass-signature']
const encryptedDataString = '... Encrypted data in Base64 ...';
const decryptedDataString = decryptData( encryptedDataString,
secretKey,
signature
);
console.log('Decrypted data object:', JSON.parse(decryptedDataString));
Decrypting Stream Files
In addition to handling encrypted data through our Public API and Webhooks, you may also need to decrypt stream files received from our services. Below are the steps and code snippets to help you decrypt these stream files effectively.
Encryption Method: For stream file operations, our system exclusively uses aes-256-cbc encryption. Regardless of any other encryption method used elsewhere in your integration, stream files must be processed using aes-256-cbc.
Key Requirement: Only the secret key is required to decrypt stream file data. No HMAC signature is needed or verified for stream files.
Implication for Alternate Methods: If you opt to use another encryption method (for example, aes-256-gcm) when handling other data, please note that stream file data will still be decrypted using aes-256-cbc with only the secret key. Any HMAC signature provided with other data is ignored for stream files.
Steps for Decrypting Stream Files
Retrieve Initialization Vector (IV): The IV for the decryption process is provided in the response headers of the stream file. You can retrieve it using the following code:
const iv = Buffer.from(response.headers['x-initialization-vector'], 'hex');
Decrypt Stream Data:
Use the IV and the encryption key to decrypt the incoming stream file data.
The length of the IV is 16 bytes.
Example Code Snippet
Here's an example of how to decrypt a stream file:
const crypto = require('crypto');
const fs = require('fs');
const http = require('http');
const { promisify } = require('util');
const { pipeline } = require('stream');
const pipelineAsync = promisify(pipeline);
async function downloadAndDecryptFile(url, outputPath, encryptionKey) {
try {
const response = await new Promise((resolve, reject) => {
const request = http.get(url, {
headers: {
'X-Private-App-Key': 'string',
},
}, (response) => {
if (response.statusCode !== 200) {
reject(new Error(`Failed to get '${url}' (${response.statusCode})`));
} else {
resolve(response);
}
});
request.on('error', (err) => {
reject(err);
});
});
// Retrieve the IV from the headers
const iv = Buffer.from(response.headers['x-initialization-vector'], 'hex');
if (!iv || iv.length !== 16) {
throw new Error('Invalid or missing initialization vector (IV)');
}
const keyBuff = Buffer.from(encryptionKey, 'hex');
// Create a decipher for decryption
const decipher = crypto.createDecipheriv('aes-256-cbc', keyBuff, iv);
// Create a write stream for the output file
const writeStream = fs.createWriteStream(outputPath);
// Pipe the encrypted stream through the decipher and into the write stream
await pipelineAsync(response, decipher, writeStream);
console.log('File downloaded and decrypted successfully.');
} catch (err) {
console.error('Error downloading or decrypting file:', err);
}
}
Last updated