devfunkd
devfunkd

Reputation: 3244

Powershell SecureString Encrypt/Decrypt To Plain Text Not Working

We are trying to store a user password in the registry as a secure string but we can not seem to find a way to convert it back to plain text. Is this possible with SecureString?

Here is the simple test script we are trying to use...

Write-Host "Test Start..."
$PlainPassword = "@SomethingStupid" | ConvertTo-SecureString -AsPlainText -Force

$BSTR = ` [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($PlainPassword)
$PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
Write-Host "Password is: " $PlainPassword
Read-Host

This is the error we are getting...

The term ' [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR'
is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\test.ps1:4 char:71
+ $BSTR = ` [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR
<<<< ($PlainPassword)
    + CategoryInfo          : ObjectNotFound: (
[System.Runtim...ureStringToBSTR:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Cannot find an overload for "PtrToStringAuto" and the argument count: "1".
At C:\test.ps1:5 char:75
+ $PlainPassword =
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto <<<< ($BSTR)
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

Upvotes: 12

Views: 40417

Answers (2)

Adi Inbar
Adi Inbar

Reputation: 12321

Here's a kludgy but much simpler way to decrypt a secure string, taking advantage of the fact that the PSCredential class has a constructor that accepts the password as a secure string and a method (GetNetworkCredential) that returns that password in plain text:

(New-Object System.Management.Automation.PSCredential 'N/A', $secure_string).GetNetworkCredential().Password

Although it's intended for use with credentials, there's nothing that prevents you from using this to decrypt any secure string* regardless of purpose, supplying a dummy argument for the username (the username argument can't be null or an empty string, but any meaningless string will do).


* Under the context of the account that encrypted the secure string to begin with, of course

Upvotes: 16

Keith Hill
Keith Hill

Reputation: 202052

What is with the backtick in the $BSTR = ... line? I agree with Graham above. If I remove the backtick it work just fine:

$PlainPassword = "@SomethingStupid" | ConvertTo-SecureString -AsPlainText -Force
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($PlainPassword)
$PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
Write-Host "Password is: " $PlainPassword

Outputs:

Password is:  @SomethingStupid

You're not trying to run this on something like Windows RT or some other PowerShell configuration where the language is restricted - are you?

Upvotes: 21

Related Questions