Skip to content

Instantly share code, notes, and snippets.

@ctigeek
Last active March 4, 2026 16:01
Show Gist options
  • Select an option

  • Save ctigeek/2a56648b923d198a6e60 to your computer and use it in GitHub Desktop.

Select an option

Save ctigeek/2a56648b923d198a6e60 to your computer and use it in GitHub Desktop.
Aes Encryption using powershell.
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
@smittix

smittix commented Apr 9, 2016

Copy link
Copy Markdown

How would you decrypt using this?

@ctigeek

ctigeek commented Apr 11, 2016

Copy link
Copy Markdown
Author

@smittix
Did you try the Decrypt-String function?

I just tested it and it worked for me:
http://pastebin.com/Yt2tpiDY

@djcasl

djcasl commented Aug 24, 2016

Copy link
Copy Markdown

Thanks for this incredible base, I did make some mods for my own purposes.

Line 9 $aesManaged.IV = [System.Convert]::FromBase64String($IV) to $aesManaged.IV = [Text.Encoding]::UTF8.GetBytes($IV)
Got an error with systemconvert
Line 17 $aesManaged.Key = [System.Convert]::FromBase64String($key) to $aesManaged.Key = [Text.Encoding]::UTF8.GetBytes($key)
Same reason

And basically this script will generate a new key everytime since you are not using a steady Init vector.
So this wil only decrypt your encrypted string in the same PS session, moment you close this, you cannot decrypt anymore.

Just to let you know.

Still many thanks, you helped me a lot.

@thanosazlin

thanosazlin commented Sep 21, 2017

Copy link
Copy Markdown

@djcasl... i'm new to ecryption, but i have encrypted via a .net application using AES, which i am looking for a way to decrypt a string that was encrypted AES in .net from powershell.. how would i use the above code just the decrypt part, to decrypt my string from .net if i know the password and salt i am using from .net ?

btw here is the .net code i'm using, from cipher_utility.cs https://bitlush.com/blog/symmetric-encryption-in-c-sharp , see AES example..

public static string Encrypt<T>(string value, string password, string salt)
             where T : SymmetricAlgorithm, new()
        {
            DeriveBytes rgb = new Rfc2898DeriveBytes(password, Encoding.Unicode.GetBytes(salt));

            SymmetricAlgorithm algorithm = new T();

            byte[] rgbKey = rgb.GetBytes(algorithm.KeySize >> 3);
            byte[] rgbIV = rgb.GetBytes(algorithm.BlockSize >> 3);
            string test = Encoding.UTF8.GetString(rgbKey);

            ICryptoTransform transform = algorithm.CreateEncryptor(rgbKey, rgbIV);

            using (MemoryStream buffer = new MemoryStream())
            {
                using (CryptoStream stream = new CryptoStream(buffer, transform, CryptoStreamMode.Write))
                {
                    using (StreamWriter writer = new StreamWriter(stream, Encoding.Unicode))
                    {
                        writer.Write(value);
                    }
                }

                return Convert.ToBase64String(buffer.ToArray());
            }
        }

@arruw

arruw commented Jan 8, 2018

Copy link
Copy Markdown

@thanosazlin I have similar problem, have you found the solution?

Thanks!

@wbrianwhite

Copy link
Copy Markdown

@djcasl... i'm new to ecryption, but i have encrypted via a .net application using AES, which i am looking for a way to decrypt a string that was encrypted AES in .net from powershell.. how would i use the above code just the decrypt part, to decrypt my string from .net if i know the password and salt i am using from .net ?

btw here is the .net code i'm using, from cipher_utility.cs https://bitlush.com/blog/symmetric-encryption-in-c-sharp , see AES example..

public static string Encrypt<T>(string value, string password, string salt)
             where T : SymmetricAlgorithm, new()
        {
            DeriveBytes rgb = new Rfc2898DeriveBytes(password, Encoding.Unicode.GetBytes(salt));

            SymmetricAlgorithm algorithm = new T();

            byte[] rgbKey = rgb.GetBytes(algorithm.KeySize >> 3);
            byte[] rgbIV = rgb.GetBytes(algorithm.BlockSize >> 3);
            string test = Encoding.UTF8.GetString(rgbKey);

            ICryptoTransform transform = algorithm.CreateEncryptor(rgbKey, rgbIV);

            using (MemoryStream buffer = new MemoryStream())
            {
                using (CryptoStream stream = new CryptoStream(buffer, transform, CryptoStreamMode.Write))
                {
                    using (StreamWriter writer = new StreamWriter(stream, Encoding.Unicode))
                    {
                        writer.Write(value);
                    }
                }

                return Convert.ToBase64String(buffer.ToArray());
            }
        }

With something like that with callouts to other functions etc, probably the easiest is to have your powershell do something like

[System.Reflection.Assembly]::LoadFrom("C:\Apps\MyApp\MyLibrary.dll") $foo = [MyLibrary.MyCrypt]::Decrypt("encryptedValue", "password", "salt")

@djcasl

djcasl commented Dec 18, 2019

Copy link
Copy Markdown

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
)

$aesManaged = New-Object "System.Security.Cryptography.AesManaged"
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::$Mode
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::$Padding
$aesManaged.BlockSize = $BSize
$aesManaged.KeySize = $MKeySize

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

@wbrianwhite

Copy link
Copy Markdown

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.

@djcasl

djcasl commented Dec 19, 2019

Copy link
Copy Markdown

@wbrianwhite Glad I could help, good luck with your scriptwork.

@Zorahn

Zorahn commented Mar 2, 2020

Copy link
Copy Markdown

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.

@djcasl

djcasl commented Mar 2, 2020

Copy link
Copy Markdown

@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.

@D3vil0p3r

D3vil0p3r commented Jun 27, 2021

Copy link
Copy Markdown

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?

@D3vil0p3r

Copy link
Copy Markdown

@alan-null

Copy link
Copy Markdown

@D3vil0p3r I created AES+GCM wrapper for my own purposes

You might find this helpful:
https://github.com/PowerShellLibrary/Crypto.AES

@D3vil0p3r

Copy link
Copy Markdown

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment