Powershell: Working with AES encryption – Part 2
Powershell PowershellIn part 1, we encrypted our credentials using an AES.key to allow it to be portable for use in multiple environments and user sessions.
In part 2 we’ll look at utilising these encrypted files in another script, but file lets talk storage, you obviously don’t want to keep these files in the same place as your script, so using a restricted network share, or Azure blob storage account with a SAS share would be recommended.
Once you’ve found a place to securely store your files, then how do we utilise them..? well it’s as easy as reading the content of each file using a get-content command in Powershell, if your using a network share you could just define the [path to the file] and read the content directly in from there, or (as I’m doing) using Azure blob storage account, you can use a Invoke-WebRequest to download the files into temporary storage locally.
network share version:
$keyfile = Get-content -path \\[unc to network share]\AES.key
$eCreds = Get-content -path \\[unc to network share]\Creds.bob
Azure Blob Storage version (and the version i will use in the rest of the script), I’ve also written this as a function so it’ll all make sense later on
# Download the AES key and credentials files
Invoke-WebRequest -Uri $aesfile -OutFile $aesoutfile
Invoke-WebRequest -Uri $credsfile -OutFile $credsoutfile
#just to give it time to download the files
Start-Sleep -Seconds 5
now lets read in these two downloaded files for working with them
# Read the AES key and encrypted credentials
$keyfile = Get-Content $aesoutfile
$eCreds = Get-Content $credsoutfile
write-host "`n"
now we have the encrypted credentials in a variable, but we need to split them up into username and password, so lets split them up
# Split the encrypted credentials into username and password parts
$splitcreds = $eCreds -Split ';'
now they’re split into an array variable, we can use the AES.key to decrypt them, but we need to convert them to a secure string first
# Decrypt the password first, then the username
$decryptedPassword = ConvertTo-SecureString $splitcreds[0] -Key $keyfile
$decryptedUsername = ConvertTo-SecureString $splitcreds[1] -Key $keyfile
now we need to use some .net InteropServices functions to convert these secure strings back to plain text
# Convert SecureString to plain text
$username = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($decryptedUsername))
$plainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($decryptedPassword))
as I’ve mentioned I’ve functionlised this script to make it easier to work with, so I’ll return the decrypted username and password
# Return the username and password as an array
return @($username, $plainPassword)
his is everything put together in a function called Get-AESCreds
function Get-AESCreds{
param (
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$aesfile,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$aesoutfile,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$credsfile,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$credsoutfile
)
# Download the AES key and credentials files
Invoke-WebRequest -Uri $aesfile -OutFile $aesoutfile
Invoke-WebRequest -Uri $credsfile -OutFile $credsoutfile
Start-Sleep -Seconds 3
# Read the AES key and encrypted credentials
$keyfile = Get-Content $aesoutfile
$eCreds = Get-Content $credsoutfile
write-host "`n"
# Split the encrypted credentials into username and password parts
$splitcreds = $eCreds -Split ' ; '
# Decrypt the password first, then the username
$decryptedPassword = ConvertTo-SecureString $splitcreds[0] -Key $keyfile
$decryptedUsername = ConvertTo-SecureString $splitcreds[1] -Key $keyfile
# Convert SecureString to plain text
$username = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($decryptedUsername))
$plainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($decryptedPassword))
#cleanup the files
remove-item -Path $aesoutfile -force
remove-item -Path $credsoutfile -force
# Return the username and password as an array
return @($username, $plainPassword)
}
nd the function uses four parameters, the source AES.key and Creds.bob, and the temporary storage for these files, below is an example (in the case of using blob storage you would just put your SAS share url’s for the source files:
Get-AESCreds -aesfile "$dir\AES.key" -aesoutfile "c:\temp\aes.key" -credsfile "$dir\Creds.bob" -credsoutfile "C:\Temp\Creds.bob"
and the output is like this:
bob@contoso.com
5up3r53cr3t!
so to use this in your script just copy the function into your script (or a PSM1 😉 ), and then call the function as required, parsing the output into a variable to use in your script.
I know you’re going to ask one question, why a .bob file, it’s a reference to Black Adder, if you know, you know 😉
Happy POSH Coding.