For ECB, CBC (Cipher Block Chaining) and CFB (Cipher Feedback Block) are block cipher modes, whereas OFB (Output feedback) and CTR (Counter) are stream cipher modes. In this case we will use a 256-bit encryption key, and with a 16-byte random salt value (IV).
AES CBC, ECB, CFB, CTS and OFB Encryption with PowerShell |
Method
For ECB, CBC (Cipher Block Chaining) and CFB (Cipher Feedback Block) are block cipher modes, whereas OFB (Output feedback) and CTR (Counter) are stream cipher modes. In this case we will use a 256-bit encryption key, and with a random salt (IV). The following code is taken from [here]:
With PowerShell, we use the System.Security.Cryptography namespace, and which is defined in the System.Security.Cryptography.Primitives.dll. There are five main cipher modes that we can use with this:
- [System.Security.Cryptography.CipherMode]::CBC
- [System.Security.Cryptography.CipherMode]::CFB
- [System.Security.Cryptography.CipherMode]::CTS
- [System.Security.Cryptography.CipherMode]::ECB
- [System.Security.Cryptography.CipherMode]::OFB
Next we can define the padding used for block modes, this include:
- [System.Security.Cryptography.PaddingMode]::PKCS7
- [System.Security.Cryptography.PaddingMode]::Zeros
- [System.Security.Cryptography.PaddingMode]::None
- [System.Security.Cryptography.PaddingMode]::ANSIX923
- [System.Security.Cryptography.PaddingMode]::ISO10126
# Taken from https://gist.github.com/ctigeek/2a56648b923d198a6e60 function Create-AesManagedObject($key, $IV, $mode) { $aesManaged = New-Object "System.Security.Cryptography.AesManaged" if ($mode="CBC") { $aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC } elseif ($mode="CFB") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CFB} elseif ($mode="CTS") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CTS} elseif ($mode="ECB") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::ECB} elseif ($mode="OFB"){$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::OFB} $aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7 $aesManaged.BlockSize = 128 $aesManaged.KeySize = 256 if ($IV) { if ($IV.getType().Name -eq "String") { $aesManaged.IV = [System.Convert]::FromBase64String($IV) } else { $aesManaged.IV = $IV } } if ($key) { if ($key.getType().Name -eq "String") { $aesManaged.Key = [System.Convert]::FromBase64String($key) } else { $aesManaged.Key = $key } } $aesManaged } function Create-AesKey() { $aesManaged = Create-AesManagedObject $aesManaged.GenerateKey() [System.Convert]::ToBase64String($aesManaged.Key) } function Encrypt-String($key, $plaintext) { $bytes = [System.Text.Encoding]::UTF8.GetBytes($plaintext) $aesManaged = Create-AesManagedObject $key $encryptor = $aesManaged.CreateEncryptor() $encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length); [byte[]] $fullData = $aesManaged.IV + $encryptedData [System.Convert]::ToBase64String($fullData) } function Decrypt-String($key, $encryptedStringWithIV) { $bytes = [System.Convert]::FromBase64String($encryptedStringWithIV) $IV = $bytes[0..15] $aesManaged = Create-AesManagedObject $key $IV $decryptor = $aesManaged.CreateDecryptor(); $unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16); $aesManaged.Dispose() [System.Text.Encoding]::UTF8.GetString($unencryptedData).Trim([char]0) } $key = Create-AesKey $plaintext = $Args[0] $mode = $Args[1] "== Powershell AES $mode Encyption==" "`nKey: "+$key $encryptedString = Encrypt-String $key $plaintext $bytes = [System.Convert]::FromBase64String($encryptedString) $IV = $bytes[0..15] "Salt: " + [System.Convert]::ToHexString($IV) "Salt: " + [System.Convert]::ToBase64String($IV) $plain = Decrypt-String $key $encryptedString "`nEncrypted: "+$encryptedString "Decrypted: "+$plain
A sample run shows:
== Powershell AES CBC Encyption== Key: NbK6+H5l6Tfze61eyPzgBAIswS+UtQYIGd40O8E1zCo= Salt: 677BF2C0D1AA2CF93379848B20BB5CE5 Salt: Z3vywNGqLPkzeYSLILtc5Q== Encrypted: Z3vywNGqLPkzeYSLILtc5XLFQUWEwdTqIo54Yjj1tYM= Decrypted: qwerty 123