Entering passwords securely in Powershell


How to enter passwords securely in Powershell and how to store and retrieve them in an encrypted file.

What’s a SecureString?

A number of commands in Powershell require you to pass sensitive credentials such as passwords as a SecureString. A SecureString represents some plain text (a string) coupled with additional security oriented features:

However SecureString is not perfectly secure. An application consuming the SecureString must be able to access the raw data contained in it. Consequently other processes - including malicious ones - can access the raw content too. A SecureString is not a securely encrypted string, rather a type of string that’s careful about how it stores it’s contents, and gives the application creating it additional control over it’s lifespan and presence in memory.

How do I create a SecureString?

There are a couple of ways to create a SecureString. The best way is to get Powershell to construct it as you type it in. In the following example Read-Host will prompt for a password with the custom prompt text “Enter Password”, convert the input to a SecureString and store it in the variable $password:

1
$password = Read-Host -AsSecureString -Prompt "Enter Password"

If you already have the password as plain text you can create one by doing:

1
$password = ConvertTo-SecureString "[email protected]" -AsPlainText -Force

This is useful if, for example, you have a password stored in the clipboard:

1
$password = Get-Clipboard | ConvertTo-SecureString -AsPlainText -Force

How do I use a SecureString?

Use any command that accepts a SecureString as a parameter. For example to unlock a BitLocker drive that was secured using a password run the following:

1
2
$password = Read-Host -AsSecureString -Prompt "Enter Password" 
Unlock-BitLocker -MountPoint D: -Password $password

How do I dispose of a SecureString?

Disposing a SecureString will release the memory resources held by the SecureString immediately, essentially removing the sensitive information from memory. To do this call .Dispose() on the SecureString variable:

1
2
3
4
$password = Read-Host -AsSecureString -Prompt "Enter Password" 
# Use $password ...
# Dispose of the SecureString instance
$password.Dispose()

How do I store credentials securely in a file?

What if we need to automate a process that requires entering credentials? We need to store the sensitive data in a secure manner. As mentioned above, SecureString doesn’t encrypt its contents securely because consuming applications need to be able to reveal it. The command ConvertFrom-SecureString can encrypt a SecureString using the current user’s Windows credentials as the encryption key:

1
2
$password = ConvertTo-SecureString "[email protected]" -AsPlainText -Force
$encryptedPassword = ConvertFrom-SecureString $password

The output is a long hexadecimal string like 46248b9c3a3f0f50... which we can save to a file, or copy to the clipboard:

1
2
3
4
# Save to a file
$encryptedPassword | Out-File "passwordFile.txt"
# Copy to the clipboard
$encryptedPassword | Set-Clipboard

To recreate a SecureString from the encrypted version we just pass the encrypted content to ConvertTo-SecureString:

1
2
3
4
# Read encrypted password from a file
$password = Get-Content "passwordFile.txt" | ConvertTo-SecureString
# Read encrypted password from the clipboard
$password = Get-Clipboard | ConvertTo-SecureString

Summary

References