安全な文字列をプレーンテキストに変換する


90

PowerShellで作業していて、ユーザーが入力したパスワードをプレーンテキストに正常に変換するコードがあります。

$SecurePassword = Read-Host -AsSecureString  "Enter password" | convertfrom-securestring | out-file C:\Users\tmarsh\Documents\securePassword.txt

私はそれを元に戻すためにいくつかの方法を試しましたが、どれも正しく機能していないようです。最近、私は以下を試しました:

$PlainPassword = Get-Content C:\Users\tmarsh\Documents\securePassword.txt

#convert the SecureString object to plain text using PtrToString and SecureStringToBSTR
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($PlainPassword)
$PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR) #this is an important step to keep things secure

これもエラーになります。

Cannot convert argument "s", with value: "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000026a5b6067d53fd43801a9ef3f8ef9e43000000000200000000000366000
0c0000000100000008118fdea02bfb57d0dda41f9748a05f10000000004800000a000000010000000c50f5093f3b87fbf9ee57cbd17267e0a10000000833d1d712cef01497872a3457bc8
bc271400000038c731cb8c47219399e4265515e9569438d8e8ed", for "SecureStringToBSTR" to type "System.Security.SecureString": "Cannot convert the "01000000
d08c9ddf0115d1118c7a00c04fc297eb0100000026a5b6067d53fd43801a9ef3f8ef9e430000000002000000000003660000c0000000100000008118fdea02bfb57d0dda41f9748a05f10
000000004800000a000000010000000c50f5093f3b87fbf9ee57cbd17267e0a10000000833d1d712cef01497872a3457bc8bc271400000038c731cb8c47219399e4265515e9569438d8e8
ed" value of type "System.String" to type "System.Security.SecureString"."
At C:\Users\tmarsh\Documents\Scripts\Local Admin Script\PlainTextConverter1.ps1:14 char:1
+ $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($PlainPassw ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

Cannot find an overload for "PtrToStringAuto" and the argument count: "1".
At C:\Users\tmarsh\Documents\Scripts\Local Admin Script\PlainTextConverter1.ps1:15 char:1
+ $PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

Cannot convert argument "s", with value: "", for "ZeroFreeBSTR" to type "System.IntPtr": "Cannot convert null to type "System.IntPtr"."
At C:\Users\tmarsh\Documents\Scripts\Local Admin Script\PlainTextConverter1.ps1:16 char:1
+ [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR) #this is an important ste ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

Password is:  01000000d08c9ddf0115d1118c7a00c04fc297eb0100000026a5b6067d53fd43801a9ef3f8ef9e430000000002000000000003660000c0000000100000008118fdea02bfb57d0dda41f97
48a05f10000000004800000a000000010000000c50f5093f3b87fbf9ee57cbd17267e0a10000000833d1d712cef01497872a3457bc8bc271400000038c731cb8c47219399e4265515e9569
438d8e8ed

誰かがこれのために働く方法を知っていますか?

回答:


117

あなたは近くにいますが、渡すパラメータSecureStringToBSTRはである必要がありSecureStringます。ConvertFrom-SecureString暗号化された標準文字列であるの結果を渡しているようです。したがってConvertTo-SecureString、に渡す前にこれを呼び出しますSecureStringToBSTR

$SecurePassword = ConvertTo-SecureString $PlainPassword -AsPlainText -Force
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

4
私はそれがうまくいくことをうれしく思います。あなたの文字列に注意して、今、それはおそらく、パスワードなどの重要な何かを含む無担保文字列変数である-それは、など、あなたのプロセスメモリ、中にはもはや安全でない
MatthewG

19
た内容に応じて、Marshal.SecureStringToBSTRのドキュメント:このメソッドは文字列のために必要な管理対象外のメモリを割り当てているのでZeroFreeBSTRメソッドを呼び出すことにより終了したときに、常にBSTRを解放します。したがって、最後に以下を実行する必要があります[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR)
Rosberg Linhares 2017年

@ RosbergLinhares-私たちは(おそらく)PowerShellに焦点を合わせているので、あなたがただできなかった理由はあります$BSTR = $nullか?
Orangutech

3
@Orangutech$nullここではアンマネージドオブジェクトを扱っているため、変数をに設定することはできません。すぐにエラーになることはありませんが、時間が経つにつれて問題が発生する可能性があると思います。
RosbergLinhares19年

1
前述のようにZeroFreeBSTR()、への呼び出しがないことに起因するメモリリークは別として、の使用PtrToStringAuto()は常に概念的に欠陥があり、PowerShellがクロスプラットフォームになったため、Unixライクなプラットフォームでは失敗します。それは常にあるべきでしたPtrToStringBSTR() -この答えを参照してください。
mklement0

84

PSCredential.GetNetworkCredential()を使用することもできます。

$SecurePassword = Get-Content C:\Users\tmarsh\Documents\securePassword.txt | ConvertTo-SecureString
$UnsecurePassword = (New-Object PSCredential "user",$SecurePassword).GetNetworkCredential().Password

私は両方の方法をテストしましたが、どちらもまだ正しいです。
Maximilian Burszley 2017年

10
Powershellyであるため、このソリューションに賛成しました。
ジム

1
System.Management.Automation.PSCredential短いタイプ名が認識されない場合、古いPSバージョンで使用します。
marsze

1
短い:[PSCredential]::new(0, $SecurePassword).GetNetworkCredential().Password
majkinetor

短い:[System.Net.NetworkCredential]::new("", $SecurePassword).Password
K.フランク

37

PowerShellで変換する最も簡単な方法

[System.Net.NetworkCredential]::new("", $SecurePassword).Password

1
実際、PSCredentialを通過する必要はありません。
NicolasMelay19年

私はこのアプローチが好きです。参考までに、互換性がおかしな人のために、このコンストラクターのオーバーロード処理SecureStringは.Net Framework4.0で導入されました。PowerShell v2で試しました (New-Object -TypeName System.Net.NetworkCredential -ArgumentList "u",$SecureString).Passwordが、残念ながら、SecureStringはサイレントにに変換されますString。呼び出しは成功したように見えPasswordますが、プロパティはリテラル値「System.Security.SecureString」になります。注意してください。
ジョンリース

19

PS 7では、あなたが使用することができますConvertFrom-SecureString-AsPlainText

 $UnsecurePassword = ConvertFrom-SecureString -SecureString $SecurePassword -AsPlainText

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/ConvertFrom-SecureString?view=powershell-7#parameters

ConvertFrom-SecureString
           [-SecureString] <SecureString>
           [-AsPlainText]
           [<CommonParameters>]

3
これは私を夢中にさせていました。私はv5でこの構文を使用しようとしても役に立ちませんでした。
トニー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.