PowerShell to iRule AES-CBC conversation using random IV values
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...1.5KViews0likes0Comments