on 25-Sep-2017 04:21
Problem this snippet solves:
Hi Folks,
I saw recently on the DevCentral boards that people are struggeling to securely exchange AES encrypted information between a Windows System and LTM.
Although some DevCentral members already managed it by using static IV (Initialization Vectors) on both sites, this approach should be considered as a very bad practise, since it allows an adversary to pulloff certain crypto analyses/attacks which could already lead to a security breach.
The snippets below will outline how to implement AES-CBC decryption/encryption with dynamic IV values on Windows using PowerShell and on LTM using iRules. The outlined snippets are alligned to each other by using the same AES crypto settings (Key-Size, Block-Size, CBC-Mode and Padding-Mode) and IV exchange techniques to become interoperable.
The implemented IV exchange technique will generate a fresh and random IV on each single encryption and simply prepended the AES-IV to the AES-Ciphertext before passing it to the receiver. The receiver then splits the received AES-Cipherstring into the contained AES-IV and AES-Ciphertext values and finally decrypt the AES-Ciphertext by using the shared AES-Key.
From Windows to LTM
1. Import the follwing PS functions on the Windows side
function Create-AesKey($KeySize) {
$AesManaged = New-Object "System.Security.Cryptography.AesManaged"
$AesManaged.KeySize = $KeySize
$AesManaged.GenerateKey()
[System.Convert]::ToBase64String($AesManaged.Key)
}
function Encrypt-Data($AesKey, $Data) {
$Data = [System.Text.Encoding]::UTF8.GetBytes($Data)
$AesManaged = New-Object "System.Security.Cryptography.AesManaged"
$AesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
$AesManaged.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
$AesManaged.BlockSize = 128
$AesManaged.KeySize = 256
$AesManaged.Key = [System.Convert]::FromBase64String($AesKey)
$Encryptor = $AesManaged.CreateEncryptor()
$EncryptedData = $Encryptor.TransformFinalBlock($Data, 0, $Data.Length);
[byte[]] $EncryptedData = $AesManaged.IV + $EncryptedData
$AesManaged.Dispose()
[System.Convert]::ToBase64String($EncryptedData)
}
function Decrypt-Data($AesKey, $Data) {
$Data = [System.Convert]::FromBase64String($Data)
$AesManaged = New-Object "System.Security.Cryptography.AesManaged"
$AesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
$AesManaged.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
$AesManaged.BlockSize = 128
$AesManaged.KeySize = 256
$AesManaged.IV = $Data[0..15]
$AesManaged.Key = [System.Convert]::FromBase64String($AesKey)
$Decryptor = $AesManaged.CreateDecryptor();
$DecryptedData = $Decryptor.TransformFinalBlock($Data, 16, $Data.Length - 16);
$aesManaged.Dispose()
[System.Text.Encoding]::UTF8.GetString($DecryptedData)
}
2. Generate a fresh 256bit AESKey on your Windows System and store it locally as well as on your F5.
Create-AesKey 256
iTEEieok7//RyzrPe5mWwz1yroPPsm4e5cqghdEHIlU=
3. Encrypt some data using the AES-Shared-Key
$encrypted = Encrypt-Data " iTEEieok7//RyzrPe5mWwz1yroPPsm4e5cqghdEHIlU=" "Hello World!"
$encrypted
W5xFrWz72U/vt95HG6fHWIuDDHpuhj2HB42E4SIrNwo=
Note: Every single encryption should have a different outcome. Thanks to the random IV!
4. Pass the AES-Cipherstring to your LTM and decrypt it using the snippet below
set aes_key [b64decode "iTEEieok7//RyzrPe5mWwz1yroPPsm4e5cqghdEHIlU="]
set aes_cipherstring [b64decode "W5xFrWz72U/vt95HG6fHWIuDDHpuhj2HB42E4SIrNwo="]
binary scan $aes_cipherstring a16a* aes_iv aes_ciphertext
set aes_plaintext [CRYPTO::decrypt -alg aes-256-cbc -key $aes_key -iv $aes_iv $aes_ciphertext]
log local0.debug "Plaintext = $aes_plaintext"
Log Output : Plaintext = Hello World!
From LTM to Windows
1. AES encrypt some data on your LTM using the snippet below
set aes_key [b64decode "iTEEieok7//RyzrPe5mWwz1yroPPsm4e5cqghdEHIlU="]
set aes_plaintext "Hello World!!"
set aes_iv [CRYPTO::keygen -alg random -passphrase "MyIVSeed" -len 128]
set aes_ciphertext [CRYPTO::encrypt -alg aes-256-cbc -key $aes_key -iv $aes_iv $aes_plaintext]
set aes_cipherstring [b64encode [binary format a*a* $aes_iv $aes_ciphertext]]
log local0.debug "Cipherstring = $aes_cipherstring"
Log Output : Cipherstring = vCIizWalo4KWO+3bLuTUp5iD0J3kArrcZS1fKDue89M=
Note: Every single encryption should also have a different outcome. Thanks to the random IV!
2. Pass the AES-Cipherstring to your Windows system and decrypt it using the snippet below
$decrypted = Decrypt-Data "iTEEieok7//RyzrPe5mWwz1yroPPsm4e5cqghdEHIlU=" "vCIizWalo4KWO+3bLuTUp5iD0J3kArrcZS1fKDue89M="
$decrypted
Hello World!!
Cheers, Kai
How to use this snippet:
See above...
Code :
See above...