Encrypt & Decrypt Data with PowerShell

Suminda Niroshan
4 min readOct 30, 2021

--

Sometimes we need to run background jobs in computers or virtual machines and those jobs may require access to certain resources or services that are password protected (or protected using any other secret). In such cases hard coding the password inside the code itself is not ideal and should be avoided at all costs.

Imagine running a background PowerShell script that upload files to a secure file share on a daily basis. Any basic (non admin) user who can read the script would be able read the password and upload their own files to the secure store or even worse delete files.

Steps should be taken to at least encrypt the secrets so they are not kept as plain text in the script itself.

This blog will cover how to do that. I have run these PowerShell commands in MacOs but these works in Windows as well. Not tested in Linux.

Prerequisites

  • A PowerShell terminal in Windows or MacOs.

You will learn

  • How to Encrypt and Decrypt data using PowerShell.

PowerShell Commands Used

ConvertFrom-SecureString - Encrypt data.

ConvertTo-SecureString - Decrypt data.

Read-Host - Read input as a secure string.

RNGCryptoServiceProvider.GetBytes - RNGCryptoServiceProvider’s GetBytes method will be used to create an encryption key which will be used for encryption and decryption.

Marshal.SecureStringToBSTR and Marshal.PtrToStringBSTR - Convert secure string to plaintext.

Encrypting Data

  • Input the data we need to encrypt into a variable called “PasswordSecureString”. This will prompt you to enter the password or secret that you need to encrypt and it will be saved to the variable. Run the following command.
$PasswordSecureString = Read-Host -AsSecureString
  • Let’s encrypt the data using following command and save it to variable “EncryptedData”.
$EncryptedData = ConvertFrom-SecureString $PasswordSecureString
  • The variable is still only saved in the current terminal session memory. If the window is closed the variable will be destroyed, so write the EncryptedData into a file with below command. You can use any file name here. Execute the following command with your file path and a file will be created in the specified file path.
$EncryptedData | Out-File -FilePath “/Users/Suminda/Desktop/secret.encrypted”

Note: Each command above was executed one by one for ease of understanding. All can be done in a one liner using Powershell pipelines (|) as below.

Now the password or the secret is safely stored in the file “secret.encrypted” and it can’t be read even if the file is opened. If someone wants to use or view the password, a PowerShell decrypt script needs to be run in order to view it. So a basic user who doesn’t have access to execute scripts won’t be able to view this.

Decrypting Data

  • Read the “secret.encrypted” file and save the content into a variable “EncryptedData” using below command.
$EncryptedData = Get-Content “/Users/Suminda/Desktop/secret.encrypted”
  • Decrypt the data and get back the secure string into a variable “PasswordSecureString” using below command.
$PasswordSecureString = ConvertTo-SecureString $EncryptedData
  • $PasswordSecureString is a SecureString object and it needs to be converted into plain text. Use the following command to save the plain text into variable “PlainTextPassword”.
$PlainTextPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($PasswordSecureString))
  • Run the following command to see the password in plain text.
$PlainTextPassword

From this point onwards the password or the secret can be used in the script that’s required to have it.

When to Use an Encryption Key

An encryption key was not used in the Encryption process done in the previous section. Since we did not specify an Encryption key, the decryption process can only be done with the same user account that encrypted the data.

The decryption will fail if,

  • Some other user account tries to decrypt.
  • If the user account password changes which was used to encrypted the data.

As you can see it’s usually better to always provide an Encryption Key as it solves the above problems.

Creating an Encryption Key

  • Execute the following command and create the Encryption Key to a file “encryption.key”.

Note: This key needs to be kept in a secure location. Keep this in a local user account specific location or limit access to it using ACLs. If this is kept in a public directory it’s pointless to create this in the first place.

Encrypt with Encryption Key

  • The only additional step we need to do is to specify the Encryption Key as a parameter to “ConvertFrom-SecureString” command.

Decrypt with Encryption Key

  • Similarly to encryption, the Encryption Key needs to be provided to “ConvertTo-SecureString” command as a parameter.
  • Run the following command to see the password in plain text.
$PlainTextPassword

Summary

Encrypting passwords or secrets needed for PowerShell scripting is always a best practice compared to hard-coding them in the script itself. Now you know how it can be done with fairly less effort.

Happy Scripting!

References

--

--