Converting SecureString to Text

by Oct 3, 2019

It can be very useful to be able to convert an encrypted SecureString back to a plain text. This way, for example, you can use PowerShell’s “masked input” features. Simply ask for a SecureString, and PowerShell takes care of masking the user input. Next, take the SecureString and turn it into a plain text so you can use it internally for whatever you like:

function Convert-SecureStringToText
{
  param
  (
    [Parameter(Mandatory,ValueFromPipeline)]
    [System.Security.SecureString]
    $Password
  )
  
  process
  {
    $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)
    [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
  }
}

$password = Read-Host -Prompt 'Enter password' -AsSecureString
$plain = Convert-SecureStringToText -Password $password

"You entered: $plain"

If you wonder why it is possible to turn a SecureString into a plain text in the first place, then be aware: SecureStrings protect string content only for 3rd party, i.e. “man-in-the-middle” attacks. It is never a protection for the person that actually entered the secret.

This also illustrates why working with credentials can be risky. When a script asks for a credential, the script can always get to the entered secret password:

$cred = Get-Credential -UserName $env:USERNAME -Message 'Enter your password'
$plain = Convert-SecureStringToText -Password $cred.Password
"You entered: $plain" 

In fact, with credential objects, it is even more trivial to get back the entered password because it has a built-in method to do just this:

$cred = Get-Credential -UserName $env:USERNAME -Message 'Enter your password'
$plain = $cred.GetNetworkCredential().Password
"You entered: $plain" 

When a script asks for a credential, make sure you trust the script (author).


Twitter This Tip! ReTweet this Tip!