AES.psm1
|
# The base code from which the comes from is from Steve Swenson and can be found # at https://gist.github.com/ctigeek/2a56648b923d198a6e60 # Steve should be congratulated. This is the cleanest and thinest of all examples that I have found. # I have forked and modified the code for this book and library # I have also modified to add proper verbs in place so that they can be used in modules # Please keep in mind that you MUST always secure your servers. # This is a wrapper so that we do not store passwords in PlainText. # The most important part here, the crux of everything, is whether or not you can # properly secure the plain text key on the server. # Weak server security is always a bad thing. # In MS Windows version of PowerShell, you may add one additional layer of security before storing # the plain text key. Convert the plain text key to a SecureString and then store an encrypted SecureString # in the file. Then, even if a would be attacker makes off with the file, it's useless since Windows DPAPI # is the base securing mechanism of the key itself. <# .Synopsis Initialize-AESCryptography creates the AES context .Description Creates the cryptography context for AES. Creates a Key and IV if not passed in. .Parameter Key A Base64 string as key, or a byte[] can be input .Example $crypto = Intialize-AESCryptography $key .Example $crypto = Intialize-AESCryptography $crypto.key > "keyfile.txt" #> function Initialize-AESCryptography($key) { $crypto = New-Object "System.Security.Cryptography.AesManaged" $crypto.Mode = [System.Security.Cryptography.CipherMode]::ECB $crypto.Padding = [System.Security.Cryptography.PaddingMode]::Zeros $crypto.BlockSize = 128 $crypto.KeySize = 256 $IV = $null if ($IV) { if ($IV.getType().Name -eq "String") { #depending on how you want to do this, you can either take a full string, not encoded #or an B64 encoded string. Comment/Uncomment what you want $crypto.IV = [System.Convert]::FromBase64String($IV) #$crypto.IV = [Text.Encoding]::UTF8.GetBytes($IV) } else { $crypto.IV = $IV } } else { #The default when called CreateEncryptor is to automatically create a Key or IV #Since we want to store the key later, better for us to do it. $crypto.GenerateIV() } if ($key) { if ($key.getType().Name -eq "String") { #depending on how you want to do this, you can either take a full string, not encoded #or an B64 encoded string. Comment/Uncomment what you want $crypto.Key = [System.Convert]::FromBase64String($key) #$crypto.Key = [Text.Encoding]::UTF8.GetBytes($key) } else { $crypto.Key = $key } } else { #The default when called CreateEncryptor is to automatically create a Key or IV #Since we want to store the key later, better for us to do it. $crypto.GenerateKey() } $crypto } <# .Synopsis Encrypts a String to AES .Description Encrypts a string to AES using key already stored in the crypto container. .Parameter crypto The cryptography container already initialized. .Parameter plaintextString A plaintext,unencrypted string to encrypt .Example $b64encryptedString = ConvertTo-AESEncryptedString $crypto $plainString #> function ConvertTo-AESEncryptedString($crypto, $unencryptedString) { $bytes = [System.Text.Encoding]::UTF8.GetBytes($unencryptedString) $encryptor = $crypto.CreateEncryptor() $encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length); #the below line isn't needed for encryption of decryption. It is just prepending the IV #[byte[]] $fullData = $crypto.IV + $encryptedData [byte[]] $fullData = $encryptedData [System.Convert]::ToBase64String($fullData) } <# .Synopsis Decrypts a Base64 encrypted string with AES .Description Provided encryption key, decrypts the input .Parameter crypto The cryptography container already initialized with KEY. .Parameter encryptedString A Base64, AES Encrypted String .Example $plainTextString = ConvertFrom-AESEncryptedString $crypto $encryptedString #> function ConvertFrom-AESEncryptedString($crypto, $encryptedString) { $bytes = [System.Convert]::FromBase64String($encryptedString) $decryptor = $crypto.CreateDecryptor(); # a little obfuscution here. This isn't even needed. #changed to not use IV in the final String #$unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16); $unencryptedData = $decryptor.TransformFinalBlock($bytes, 0, $bytes.Length); #The below line shouldn't need to Trim Zeros (which was the pad) [System.Text.Encoding]::UTF8.GetString($unencryptedData).Trim([char]0) } |