Encryption
All communication between AnnA and the Client travels with 3DES symmetric encryption using CBC (Cipher Block Chaining) mode with block size of 64 and key size of 192 bytes
Below we have some examples on how to implement the methods of encryption and decryption:
public static string Encrypt3DES(string data, string key, string iv)
{
byte[] bytes = Encoding.UTF8.GetBytes(data);
byte[] decodedKey = Convert.FromBase64String(key);
byte[] decodedIv = Convert.FromBase64String(iv);
var cryptoServiceProvider = new TripleDESCryptoServiceProvider()
{
Key = decodedKey,
IV = decodedIv,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7
};
byte[] encrypted = cryptoServiceProvider.CreateEncryptor().TransformFinalBlock(bytes, 0, bytes.Length);
cryptoServiceProvider.Clear();
return Convert.ToBase64String(encrypted);
}
public static string Decrypt3DES(string data, string key, string iv)
{
byte[] encryptedBytes = Convert.FromBase64String(data);
byte[] decodedKey = Convert.FromBase64String(key);
byte[] decodedIv = Convert.FromBase64String(iv);
var cryptoServiceProvider = new TripleDESCryptoServiceProvider()
{
Key = decodedKey,
IV = decodedIv,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7
};
byte[] bytes = cryptoServiceProvider.CreateDecryptor().TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
cryptoServiceProvider.Clear();
return Encoding.UTF8.GetString(bytes);
}
public static string GenerateIV()
{
var cryptoServiceProvider = new TripleDESCryptoServiceProvider();
cryptoServiceProvider.GenerateIV();
return Convert.ToBase64String(cryptoServiceProvider.IV);
}
public static string Encrypt3DES(string data, string key, string IV)
{
byte[] bytes = Encoding.UTF8.GetBytes(data);
byte[] convertedKey = Convert.FromBase64String(key);
byte[] convertedIV = Convert.FromBase64String(IV);
var cryptoServiceProvider = TripleDES.Create();
cryptoServiceProvider.Key = convertedKey;
cryptoServiceProvider.IV = convertedIV;
cryptoServiceProvider.Mode = CipherMode.CBC;
cryptoServiceProvider.Padding = PaddingMode.PKCS7;
byte[] inArray = cryptoServiceProvider.CreateEncryptor().TransformFinalBlock(bytes, 0, bytes.Length);
cryptoServiceProvider.Clear();
return Convert.ToBase64String(inArray, 0, inArray.Length);
}
public static string Decrypt3DES(string data, string key, string IV)
{
byte[] inputBuffer = Convert.FromBase64String(data);
byte[] convertedKey = Convert.FromBase64String(key);
byte[] convertedIV = Convert.FromBase64String(IV);
var cryptoServiceProvider = TripleDES.Create();
cryptoServiceProvider.Key = convertedKey;
cryptoServiceProvider.IV = convertedIV;
cryptoServiceProvider.Mode = CipherMode.CBC;
cryptoServiceProvider.Padding = PaddingMode.PKCS7;
byte[] bytes = cryptoServiceProvider.CreateDecryptor().TransformFinalBlock(inputBuffer, 0, inputBuffer.Length);
cryptoServiceProvider.Clear();
return Encoding.UTF8.GetString(bytes);
}
public static string GenerateIV()
{
var auxTdes = TripleDES.Create();
auxTdes.GenerateIV();
byte[] IVArray = auxTdes.IV;
string IV = Convert.ToBase64String(IVArray);
return IV;
}
public String encrypt(String message, SecretKey key, IvParameterSpec iv) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] plainTextBytes = message.getBytes("utf-8");
byte[] buf = cipher.doFinal(plainTextBytes);
byte[] base64Bytes = Base64.getEncoder().encode(buf);
String base64EncryptedString = new String(base64Bytes);
return base64EncryptedString;
}
public String decrypt(String encMessage, SecretKey key, IvParameterSpec iv) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
byte[] message = Base64.getDecoder().decode(encMessage.getBytes("utf-8"));
final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
decipher.init(Cipher.DECRYPT_MODE, key, iv);
byte[] plainText = decipher.doFinal(message);
return new String(plainText, "UTF-8");
}
function encrypt3DES($data, $key, $IV)
{
$IV = base64_decode($IV);
$key = base64_decode($key);
return openssl_encrypt($data, 'des-ede3-cbc', $key, 0, $IV);
}
function decrypt3DES($data, $deckey, $IV)
{
$IV = base64_decode($IV);
$deckey = base64_decode($deckey);
return openssl_decrypt($data, 'des-ede3-cbc', $deckey, 0, $IV);
}
from flask import Flask, request, Response
from flask_ngrok import run_with_ngrok
import json
from Crypto.Cipher import AES, DES3, DES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
from base64 import b64encode, b64decode
# Initialising a web application with flask
app = Flask(__name__)
# For this integration example, NGROK was used to emulate a response server
run_with_ngrok(app)
# Encryption method
def encrypt(data, enckey, iv):
enckey = b64decode(enckey)
iv = b64decode(iv)
cipher = DES3.new(enckey, DES3.MODE_CBC, iv)
ct_bytes = cipher.encrypt(
pad(bytes(data, encoding='utf-8'), DES3.block_size))
ciphertext = b64encode(ct_bytes).decode('utf-8')
return ciphertext
# Decryption method
def decrypt(data, deckey, iv):
try:
deckey = b64decode(deckey)
iv = b64decode(iv)
data = b64decode(data)
cipher = DES3.new(deckey, DES3.MODE_CBC, iv)
pt = unpad(cipher.decrypt(data), DES3.block_size)
return pt
except (ValueError, KeyError):
return 'Incorrect decryption'
# Get POST AnnA
@app.route('/get-post', methods=['POST'])
def receber_post():
# Encryption Keys
enckey = 'ENCRYPTION_KEY'
deckey = 'DECRYPTION_KEY'
# Retrieving the form sent by AnnA
data = request.form
# Recovering the received IV
ivReceived = data.get('ANNAEXEC')
# Creating the structure of an AnnA message
nodeMessage = [
{
"PropName": "Alias",
"PropValue": "msg001"
},
{
"PropName": "Type",
"PropValue": "MESSAGE"
},
{
"PropName": "Phrase",
"PropValue": "Hello World!"
}
]
# Creating the container structure
container = [
{
"PropName": "Container001",
"PropValue": json.dumps(nodeMessage)
}
]
# Creating a new IV and encrypting it
key = get_random_bytes(8)
cipher = DES.new(key, DES3.MODE_CBC)
newIV = b64encode(cipher.iv).decode('utf-8')
# Serialising the container structure and encrypting it
serialisedContainer = json.dumps(container)
encryptedSerialisedContainer = encrypt(serialisedContainer, enckey, newIV)
# Encrypting the new IV
newIVEncrypted = encrypt(newIV, deckey, ivReceived)
# Configuring response for AnnA
replyToAnnA = encryptedSerialisedContainer + ivReceived + newIVEncrypted
# Replying to AnnA
response = Response(replyToAnnA, content_type='text/plain')
# Log
print('\nData received from AnnA:', data)
print('\nIV Received:', ivReceived)
print('\n')
print('\nNode Message:', nodeMessage)
print('\nContainer:', container)
print('\nContainer Serialised:', serialisedContainer)
print('\nContainer Serialised Encrypted:', encryptedSerialisedContainer)
print('\n')
print('\nNew IV:', newIV)
print('\nNew IV Encrypted:', newIVEncrypted)
print('\n')
print('\nReply To AnnA:', replyToAnnA)
print('\nResponse From AnnA:', response)
return response
if __name__ == '__main__':
app.run()