Encrypt values using AES RSA in Powershell

You can encrypt a password so that only under your account it can be decrypted. If however you need some other user to decrypt the data the code is worthless. You can use different code for this case. You need a certificate with private key. It can be a certificate that is self signed. You can use byte values of a maximum van 32 (equals 256 bit). I would recommend using a 32 Byte value. Get the thumbprint value using the following code:

Get-Item -Path Cert:\CurrentUser\My\*

Of course you can also use a certificate that is installed on the local machine. For the sake of better security I would use a certificate that is installed in the CurrentUser part of the certificate store.

If you know the thumbprint of the certificate, state that value in the $thumbprint string. Enter the plaintext value which you want to encrypt in the string $Securestring. Configure the Export-Clixml path to you liking. You can change the name of the XML file without voiding the abillity to decrypt.

try
{
    $secureString = 'StrongPassword' | 
                    ConvertTo-SecureString -AsPlainText -Force

    # Generate our new 32-byte AES key.  I don't recommend using Get-Random for this; the System.Security.Cryptography namespace
    # offers a much more secure random number generator.

    $key = New-Object byte[](32)
    $rng = [System.Security.Cryptography.RNGCryptoServiceProvider]::Create()

    $rng.GetBytes($key)

    $encryptedString = ConvertFrom-SecureString -SecureString $secureString -Key $key

    # This is the thumbprint of a certificate on my test system where I have the private key installed.Note that the thumbprint value is CASE SENSITIVE

    $thumbprint = 'D180EA99616A925E716278635E29159BC7105663'
    $cert = Get-Item -Path Cert:\CurrentUser\My\$thumbprint -ErrorAction Stop

    $encryptedKey = $cert.PublicKey.Key.Encrypt($key, $true)

    $object = New-Object psobject -Property @{
        Key = $encryptedKey
        Payload = $encryptedString
    }

    $object | Export-Clixml .\encryptionTest2.xml

}
finally
{
    if ($null -ne $key) { [array]::Clear($key, 0, $key.Length) }

You can decrypt the value securely using the following code:

try
{
    $object = Import-Clixml -Path .\encryptionTest2.xml

    $thumbprint = 'D180EA99616A925E716278635E29159BC7105663'
    $cert = Get-Item -Path Cert:\CurrentUser\My\$thumbprint -ErrorAction Stop

    $key = $cert.PrivateKey.Decrypt($object.Key, $true)

    $secureString = $object.Payload | ConvertTo-SecureString -Key $key 
	
}
finally
{
    if ($null -ne $key) { [array]::Clear($key, 0, $key.Length) }
}

$cred = New-Object System.Management.Automation.PSCredential(Useraccount, $secureString)

Now you can run command’s under an account without having to compromise the password easily. You need to have the certificate to decrypt.  Don’t try to encrypt the username also. Powershell does not accept secure usernames somehow.  An example of how to use this would be:

Import-Module ActiveDirectory
$Username = [Environment]::UserName
Get-ADUser -Identity $Username -Credential $Cred

To troubleshoot you can decrypt the password in plain text using the following code. Please note that this leaves the unencrypted password in the memory waiting to be exploited.

$cred = New-Object System.Management.Automation.PSCredential('Username', $secureString)
$plainText = $cred.GetNetworkCredential().Password
Write-Host $Plaintext