grokgarble.com

Database, Software, and System Engineering

Asymmetric Encryption of Text using x.509 Certificates in PowerShell

I’ve been requested to encryption sections of my script (user name/password) using a certificate issued by a trusted CA.  No problem.

To do this in the blog, I’ll I created a self-signed x.509 certificate and a CN of “PowerShellCert”.  I will use the public portion of the certificate in a file that’s base64 .cer to encrypt the sections. That certificate I’ll place in the Windows key store and referenced by thumbprint for decryption.  For the actual work, I’ll import the CA trusted certificate into the same key store, replace the thumbprint with that CA trusted one and make sure the certificate is trusted either by the user or machine the script is running.

Here’s the command used with the makecert utility to create a 2048 length cert:

C:\Program Files\Microsoft SDKs\Windows\v7.1>makecert.exe -r -pe -n "CN=PowerShellCert" -ss my -sr localmachine -eku 1.3.6.1.5.5.7.3.2 -len 2048 -e 01/01/2030 C:\Scripts\PowerShell\Asymmetrical-Encryption\PowerShellAsymmetrical.cer

Here’s the encryption function:

Function Encrypt-Asymmetric {
	[CmdletBinding()]
	[OutputType([System.String])]
	param(
		[Parameter(Position=0, Mandatory=$true)][ValidateNotNullOrEmpty()][System.String]
		$ClearText,
		[Parameter(Position=1, Mandatory=$true)][ValidateNotNullOrEmpty()][ValidateScript({Test-Path $_ -PathType Leaf})][System.String]
		$PublicCertFilePath
	)
    # Encrypts a string with a public key
    $PublicCert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($PublicCertFilePath)
    $ByteArray = [System.Text.Encoding]::UTF8.GetBytes($ClearText)
	$EncryptedByteArray = $PublicCert.PublicKey.Key.Encrypt($ByteArray,$true)
	$Base64String = [Convert]::ToBase64String($EncryptedByteArray)

	Return $Base64String 
}

…here’s the decryption function:

Function Decrypt-Asymmetric
{
	[CmdletBinding()]
	[OutputType([System.String])]
	param(
		[Parameter(Position=0, Mandatory=$true)][ValidateNotNullOrEmpty()][System.String]
		$EncryptedBase64String,
		[Parameter(Position=1, Mandatory=$true)][ValidateNotNullOrEmpty()][System.String]
		$CertThumbprint
	)
    # Decrypts cipher text using the private key
    # Assumes the certificate is in the LocalMachine\My (Personal) Store
    $Cert = Get-ChildItem cert:\LocalMachine\My | where { $_.Thumbprint -eq $CertThumbprint }
	if($Cert) {
	    $EncryptedByteArray = [Convert]::FromBase64String($EncryptedBase64String)
	    $ClearText = [System.Text.Encoding]::UTF8.GetString($Cert.PrivateKey.Decrypt($EncryptedByteArray,$true))
    }
	Else {Write-Error "Certificate with thumbprint: $CertThumbprint not found!"}

	Return $ClearText
}

To Encrypt clear text:

PS C:\>Encrypt-Asymmetric -ClearText "CLEAR TEXT DATA" -PublicCertFilePath "C:\Scripts\PowerShell\Asymmetrical-Encryption\PowerShellAsymmetricalTest.cer"

To Decrypt clear text:

PS C:\>Decrypt-Asymmetric -EncryptedBase64String $Base64String -CertThumbprint "83D2D68907681EF3D823B23DEE24B0CBB3FA3C51"

To find your Certificate’s thumbprint (assuming you gave it the same name as I did above):

PS C:\> Get-ChildItem cert:\LocalMachine\My | where { $_.Subject -eq "CN=PowerShellCert" } | select Thumbprint

Now, encryption keys can be garded under the Windows key store.

Share on Tumblr

, ,

Leave a Reply

Connect with:

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Current ye@r *