Encryption in OnePipe
This document provides details on how to implement the various aspects of encryption used in OnePipe.
Triple DES Algorithm
In cryptography, Triple DES (3DES or TDES), officially the Triple Data Encryption Algorithm (TDEA or Triple DEA), is a symmetric-key block cipher, which applies the DES cipher algorithm three times to each data block.
See details here.
Sample Code Snippets
JAVA (Encryption)
public String encrypt(String ToBeEncrypted, String SecretKey) {
try{
MessageDigest md = MessageDigest.getInstance("md5");
byte[] digestOfPassword = md.digest(SecretKey.getBytes("UTF-16LE"));
byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
SecretKey secretKey = new SecretKeySpec(keyBytes,"DESede");
IvParameterSpec iv = new IvParameterSpec(new byte[8]);
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
byte[] plainTextBytes = ToBeEncrypted.getBytes("UTF-16LE");
byte[] cipherText = cipher.doFinal(plainTextBytes);
byte [] base64Bytes = Base64.encodeBase64(cipherText);
return new String(base64Bytes);
}
catch (Exception e){
e.printStackTrace();
}
return ToBeEncrypted;
}
JAVA (Decryption)
public String decrypt(String encryptedText, String secretKey) {
try{
byte[] message = Base64.decodeBase64(encryptedText.getBytes("UTF-16LE"));
MessageDigest md = MessageDigest.getInstance("md5");
byte[] digestOfPassword = md.digest(secretKey.getBytes("UTF-16LE"));
byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
SecretKey key = new SecretKeySpec(keyBytes, "DESede");
IvParameterSpec iv = new IvParameterSpec(new byte[8]);
Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
decipher.init(Cipher.DECRYPT_MODE, key, iv);
byte[] plainText = decipher.doFinal(message);
return new String(plainText, "UTF-16LE");
}
catch (Exception e){
e.printStackTrace();
}
return encryptedText;
}
C# (Encryption)
string encryptedText = "";
MD5 md5 = new MD5CryptoServiceProvider();
TripleDES des = new TripleDESCryptoServiceProvider();
des.KeySize = 128;
des.Mode = CipherMode.CBC;
des.Padding = PaddingMode.PKCS7;
byte[] md5Bytes = md5.ComputeHash(Encoding.Unicode.GetBytes(key));
byte[] ivBytes = new byte[8];
des.Key = md5Bytes;
des.IV = ivBytes;
byte[] clearBytes = Encoding.Unicode.GetBytes(TextToEncrypt);
ICryptoTransform ct = des.CreateEncryptor();
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
encryptedText = Convert.ToBase64String(ms.ToArray());
}
return encryptedText;
C# (Decryption)
string decryptedText = "";
MD5 md5 = new MD5CryptoServiceProvider();
TripleDES des = new TripleDESCryptoServiceProvider();
des.KeySize = 128;
des.Mode = CipherMode.CBC;
des.Padding = PaddingMode.PKCS7;
byte[] md5Bytes = md5.ComputeHash(Encoding.Unicode.GetBytes(key));
byte[] ivBytes = new byte[8];
des.Key = md5Bytes;
des.IV = ivBytes;
byte[] clearBytes = Convert.FromBase64String(TextTodecrypt);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
decryptedText = Encoding.UTF8.GetString(ms.ToArray());
}
if (!replaceSpace)
{
return decryptedText.Replace("\0", "");
}
return decryptedText.Replace("\0", "").TrimEnd();
}
PHP (Encryption and Decryption)
function encryption($encryption_key,$data)
{
$method = "des-ede3-cbc";
$source = mb_convert_encoding($key, 'UTF-16LE', 'UTF-8');
$key = md5($source, true);
$key .= substr($key, 0, 16);
$iv = "\0\0\0\0\0\0\0\0"; //Pad for PKCS7
$encData = openssl_encrypt($data,$method, $key, $options=OPENSSL_RAW_DATA, $iv);
return base64_encode($encData);
}
function decryption($key, $data){
try {
$method = "des-ede3-cbc";
$source = mb_convert_encoding($key, 'UTF-16LE', 'UTF-8');
$key = md5($source, true);
$key .= substr($key, 0, 8);
$data = base64_decode($data);
//Pad for PKCS7
$iv = "\0\0\0\0\0\0\0\0";
$decData = openssl_decrypt($data,$method,$key,$options=OPENSSL_RAW_DATA,$iv);
$splitedString = explode("\u0000", json_encode($decData));
$result = array_filter($splitedString, function($v){
return "\u0000" != $v;
});
return json_decode(join($result), true);
} catch (\Exception $e) {
log_message('error', "Decryption error =>" . $e->getMessage());
return $e;
}
}
JavaScript (Encryption and Decryption)
const crypto = require("crypto");
function encrypt(sharedKey, plainText) {
const bufferedKey = Buffer.from(sharedKey, "utf16le");
const key = crypto
.createHash("md5")
.update(bufferedKey)
.digest();
const newKey = Buffer.concat([key, key.slice(0, 8)]);
const IV = Buffer.alloc(8, "\0");
const cipher = crypto
.createCipheriv("des-ede3-cbc", newKey, IV)
.setAutoPadding(true);
return cipher.update(plainText, "utf8", "base64") + cipher.final("base64");
}
function decrypt(sharedKey, cipherText) {
const bufferedKey = Buffer.from(sharedKey, "utf16le");
const key = crypto
.createHash("md5")
.update(bufferedKey)
.digest();
const newKey = Buffer.concat([key, key.slice(0, 8)]);
const IV = Buffer.alloc(8, "\0");
const cipher = crypto
.createDecipheriv("des-ede3-cbc", newKey, IV)
.setAutoPadding(true);
return cipher.update(cipherText, "base64", "utf8") + cipher.final("utf8");
}
module.exports = { encrypt, decrypt };
Applications of Triple DES in OnePipe
OnePipe uses the Triple DES algorithm to encrypt/decrypt sensitive information in request payloads during http requests. Below gives the different aspects where this algorithm is used:
App → OnePipe: The
auth.secure
in the standard OnePipe app request payload is used for holding sensitive data that needs to be encrypted. Ifauth.secure
has a value, then it needs to be encrypted with the Triple DES algorithm, using the app’s secret key.
Below shows a sample App → OnePipe request with an encrypted secure.
{
"request_ref":"{{request_ref}}",
"request_type":"collect",
"auth": {
"type": "card",
"secure": "wRE6vLhyhc62hjskdu29jcjg54gj789ol6hD4==", //encrypted secure
"auth_provider": "Beeceptor",
"route_mode": null
},
"transaction": {
"mock_mode": "live",
"transaction_ref": "{{transaction_ref}}",
"transaction_desc": "A random transaction",
"transaction_ref_parent": null,
"amount": 10000,
"customer":{
"customer_ref": "234802343132",
"firstname": "Uju",
"surname": "Usmanu",
"email": "ujuusmanu@gmail.com",
"mobile_no": "234802343132"
},
"meta":{
"a_key":"a_meta_value_1",
"another_key":"a_meta_value_2"
},
"details": null
}
}
NOTE: When a card is to be encrypted, auth.secure should hold the encrypted value of:TripleDES.encrypt("{card.Pan};{card.Cvv};{card.Expdate};{card.Pin}",secretKey)
Eg: TripleDES.encrypt("5061000453765410221;657;0922;1234",secretKey)
OnePipe → Provider Microservice: Here, the whole request payload is encrypted with the Triple DES algorithm. The secret key used for the encryption is configurable from the provider implementation, on the OnePipe console.
Below shows a sample OnePipe → Provider MS request payload.
{
"data":"PSU1TYNyqWjruSqsAWtyLmpethiA5ONHNJ0i1SUQSBlOjFRAI1njsUqtNquYXns/dbSw5z3se5P87Tpfi6W+hZcqOCk1TAQ1oG50OsjKzNLqlFyUSStDkU6DuCsfpl8pNnxQHmAel6PonFo+G1wO5dHYNbYmwdEUjwqEUJ6JvIOnLBX4JHgDqSoe6KXvBEUn/rIS+CPFsjHW23I3+I4gSTyacXPuuaiWFClwwGwTfbI8JPpgCZVMUC45/PKKNpGMMHCQuBQv9/h1aJ6RO/DDXtuQYYFFuJIMg9M0IYxH0c4BnX/dj8LuHWKs5DcvfQ7d/SEgv6YPqY8imVG2pcppSijYprljO+o88/DyrE0TWVwQF4KFbyBg5BfF6kp11tf5w4F5aYD9vLPBC39SPGgpr/Ouqz2C4nErA6gHAWmsfuAKIn8p8sdfEMWn2FvmRPG+W04v9rEnfbc8ENSwlHoZSHVZ/zEuKqDfoyMtw64O8jusucAm9tpjiqQW8+cTQJs3ZpHE8irVnZ3lMEZ1Pl99dw0enUbXxfAzG7D/x+KAybAaApeUWMrx9b+1GCu+3PUZalaOv7cc96A0butAT4T4X8qPhIaULN0vxD/QPxrWxGcCVkrp9bcNC2csSwiUNqzvJ7O2Wes3hcLou65Ek3Oto3mna7uIHVA/Fx6CYYu+dvF3UvKPRLpUxfrJUMxeHRZcYKqE90lL5txZuc+3P0PDRTLWgNx7IHv3ozQsxfwli4uuJU3t7dDGmBQ/ikHySxTugQb9TK6HTLuPFAxxOtJBiBMXsUnwwzjQ9k5lXH66mNUIQluwOPKOqGl3LOKTNR9m3nF+FyVIKzCV7q5ynd9VEwvnubNyxTqMC+Ppu2LHdsGXaNl79Hmp3veW6ygb/jhvZ8n5onX69Ak5YxWcsoXn7d6u9tLYivVtOm9wWZNm7BpSNqIEd/gRSvkbaRFb2DK/LZOY3l0bhaygFHNAWdz3DXUheYYVgqPcmhD1XX14hLe9+GvEl76GTRVc5WAoTwd6you+xApJAcvH22QcaPhHzX87WbYzvnDIE8qfIUjH4ceFWlqAl/nQ8lajUpzRO6T4oO72Hnaydi8lKJW1UXaNI55keCmvwQwKd3XM985gy3Qz7pSEeJf9/01z8hm3NUbXMEPWUzdX/wVHx4Rbh5TNa7Cb/BUwhY0NJuAZTDHBMHbF6gmqPEj+ipKLiGebmoetCkCM1Q/E8cl5V7V1JPNAvNo4DptNvHlRTzFDbDyhcBvp/R2d0fVC917ExgME8qOnsVBrfPQE4Uy3V1lgbCcVejkRpdUK8fBaXmWQgOiA7O32x+QfZTeNv0IAYpog3Zg/2t/TauehDuJrqmVkCi1JSocx3So4vF2lG0sdh/AMNCjCjut8xcXXzT+dcYfsCrvaO4WFVWv0lwmLejh3LfH3voXgfUeJ2NFbF7jlaGfg76dfHzHxNAx5PNeUXVoNzyXvHk6o+wmEX0u2ozp6LP9Yu7e7lFfxnevOP1E/CPE4yAuk"
}
Provider Microservice → OnePipe: Here, the whole response payload is encrypted with the Triple DES algorithm. The secret key used for the encryption is configurable from the provider implementation, on the OnePipe console.
Below shows a sample Provider MS → OnePipe response payload.
{
"data":"PSU1TYNyqWjruSqsAWtyLmpethiA5ONHNJ0i1SUQSBlOjFRAI1njsUqtNquYXns/dbSw5z3se5P87Tpfi6W+hZcqOCk1TAQ1oG50OsjKzNLqlFyUSStDkU6DuCsfpl8pNnxQHmAel6PonFo+G1wO5dHYNbYmwdEUjwqEUJ6JvIOnLBX4JHgDqSoe6KXvBEUn/rIS+CPFsjHW23I3+I4gSTyacXPuuaiWFClwwGwTfbI8JPpgCZVMUC45/PKKNpGMMHCQuBQv9/h1aJ6RO/DDXtuQYYFFuJIMg9M0IYxH0c4BnX/dj8LuHWKs5DcvfQ7d/SEgv6YPqY8imVG2pcppSijYprljO+o88/DyrE0TWVwQF4KFbyBg5BfF6kp11tf5w4F5aYD9vLPBC39SPGgpr/Ouqz2C4nErA6gHAWmsfuAKIn8p8sdfEMWn2FvmRPG+W04v9rEnfbc8ENSwlHoZSHVZ/zEuKqDfoyMtw64O8jusucAm9tpjiqQW8+cTQJs3ZpHE8irVnZ3lMEZ1Pl99dw0enUbXxfAzG7D/x+KAybAaApeUWMrx9b+1GCu+3PUZalaOv7cc96A0butAT4T4X8qPhIaULN0vxD/QPxrWxGcCVkrp9bcNC2csSwiUNqzvJ7O2Wes3hcLou65Ek3Oto3mna7uIHVA/Fx6CYYu+dvF3UvKPRLpUxfrJUMxeHRZcYKqE90lL5txZuc+3P0PDRTLWgNx7IHv3ozQsxfwli4uuJU3t7dDGmBQ/ikHySxTugQb9TK6HTLuPFAxxOtJBiBMXsUnwwzjQ9k5lXH66mNUIQluwOPKOqGl3LOKTNR9m3nF+FyVIKzCV7q5ynd9VEwvnubNyxTqMC+Ppu2LHdsGXaNl79Hmp3veW6ygb/jhvZ8n5onX69Ak5YxWcsoXn7d6u9tLYivVtOm9wWZNm7BpSNqIEd/gRSvkbaRFb2DK/LZOY3l0bhaygFHNAWdz3DXUheYYVgqPcmhD1XX14hLe9+GvEl76GTRVc5WAoTwd6you+xApJAcvH22QcaPhHzX87WbYzvnDIE8qfIUjH4ceFWlqAl/nQ8lajUpzRO6T4oO72Hnaydi8lKJW1UXaNI55keCmvwQwKd3XM985gy3Qz7pSEeJf9/01z8hm3NUbXMEPWUzdX/wVHx4Rbh5TNa7Cb/BUwhY0NJuAZTDHBMHbF6gmqPEj+ipKLiGebmoetCkCM1Q/E8cl5V7V1JPNAvNo4DptNvHlRTzFDbDyhcBvp/R2d0fVC917ExgME8qOnsVBrfPQE4Uy3V1lgbCcVejkRpdUK8fBaXmWQgOiA7O32x+QfZTeNv0IAYpog3Zg/2t/TauehDuJrqmVkCi1JSocx3So4vF2lG0sdh/AMNCjCjut8xcXXzT+dcYfsCrvaO4WFVWv0lwmLejh3LfH3voXgfUeJ2NFbF7jlaGfg76dfHzHxNAx5PNeUXVoNzyXvHk6o+wmEX0u2ozp6LP9Yu7e7lFfxnevOP1E/CPE4yAuk"
}