-
-
Save ctigeek/2a56648b923d198a6e60 to your computer and use it in GitHub Desktop.
function Create-AesManagedObject($key, $IV) { | |
$aesManaged = New-Object "System.Security.Cryptography.AesManaged" | |
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC | |
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros | |
$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, $unencryptedString) { | |
$bytes = [System.Text.Encoding]::UTF8.GetBytes($unencryptedString) | |
$aesManaged = Create-AesManagedObject $key | |
$encryptor = $aesManaged.CreateEncryptor() | |
$encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length); | |
[byte[]] $fullData = $aesManaged.IV + $encryptedData | |
$aesManaged.Dispose() | |
[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 | |
$key | |
$unencryptedString = "blahblahblah" | |
$encryptedString = Encrypt-String $key $unencryptedString | |
$backToPlainText = Decrypt-String $key $encryptedString |
Thanks for the reply 😀
We had a choco package that depended on another choco package that installed a dotNet console app to do encryption, but had some issues when the dependency resolution in some cases, so we were looking for a simple way to do encryption directly in the chocoInstall.ps1.
@wbrianwhite Glad I could help, good luck with your scriptwork.
Hey, just tried your functions today, and thanks, looks great. Good job
I did, however get an error after updating with your latest notes. The size of the key is invalid when I use $aesManaged.Key = [Text.Encoding]::UTF8.GetBytes($key) , but when I switch back to FromBase64String it works..
Pretty new to this whole encryption thing, so no idea why, but probably something I've forgotten.. Anyway, works with the first part.
@Zorahn , might have something to do with the characterset you are using. But that is the main reason when I make changes like this, I always put the old stuff in the comments. Please note I am not the original creator of this Example so all credits go to @ctigeek
Glad it works for you, Encryption is a very tricky thing. It took me a while as well to get it working for my purpose.
Very nice project in PowerShell.
As block cipher mode, I see that we can only use the following: CBC,ECB,OFB,CFB,CTS.
How can we implement the GCM in this code?
Up @ctigeek
@D3vil0p3r I created AES+GCM wrapper for my own purposes
You might find this helpful:
https://github.com/PowerShellLibrary/Crypto.AES
@D3vil0p3r I created AES+GCM wrapper for my own purposes
You might find this helpful: https://github.com/PowerShellLibrary/Crypto.AES
Thank you @alan-null I appreciate this. I will give a look to it in the next days.
Didn't know anyone was still using / reading this.
My last comment was from three years ago, but now there should be way better ways to do this.
My Script that uses this, still works though.
Usage is basically:
$encryptedString = Encrypt-String $key $unencryptedString
$backToPlainText = Decrypt-String $key $encryptedString
Things you should keep in mind, that Padding is very important. The padding used here is:
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
I on the other hand use $aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
More info on padding
If I would use this code now, I would rebuild the top like:
function Create-AesManagedObject
{
Param
(
#Dont's declare Key and IV type so you can use anything (dirty powershelling)
$key,
$IV,
#I Declared an IV Const byte array variable before this function
[string] $Mode = "CBC",
[string]$Padding = "PKCS7",
[int] $BSize = 128,
[int] $MKeySize = 256
)
This Part I changes as well
if ($IV) {
if ($IV.getType().Name -eq "String") {
#was $aesManaged.IV = [System.Convert]::FromBase64String($IV)
$aesManaged.IV = [Text.Encoding]::UTF8.GetBytes($IV)
}
else {
$aesManaged.IV = $IV
}
}
if ($key) {
if ($key.getType().Name -eq "String") {
#was $aesManaged.Key = [System.Convert]::FromBase64String($key)
$aesManaged.Key = [Text.Encoding]::UTF8.GetBytes($key)
}
else {
$aesManaged.Key = $key
}
Last note:
I would also put al these functions in a seperate module now. To keep the main code cleaner, but that is also up to you
Easiest way I do this.
$custommodule = \FULLPath\modulename.psm1"
Import-Module -DisableNameChecking $custommodule