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:
- The raw data is obfuscated rather than stored as plain text.
- It’s ‘pinned’ in memory, i.e. it won’t get moved around or copied when the operating system is trying to optimize resources.
- When it’s disposed, the memory it occupies is freed immediately.
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
:
|
|
If you already have the password as plain text you can create one by doing:
|
|
This is useful if, for example, you have a password stored in the clipboard:
|
|
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:
|
|
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:
|
|
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:
|
|
The output is a long hexadecimal string like 46248b9c3a3f0f50...
which we can save to a file, or copy to the clipboard:
|
|
To recreate a SecureString
from the encrypted version we just pass the encrypted content to ConvertTo-SecureString
:
|
|
Summary
SecureString
does not encrypt sensitive information securely, but it’s better than plain text.- Use
Read-Host -AsSecureString
orConvertTo-SecureString
to createSecureString
s. - Call
.Dispose()
on theSecureString
instance to remove it from memory immediately. - Use
ConvertFrom-SecureString
to encrypt aSecureString
using the current user’s credentials, andConvertTo-SecureString
to do the reverse.