将安全字符串转换为纯文本

tma*_*rsh 64 powershell securestring

我正在使用power shell,我有成功将用户输入的密码转换为纯文本的代码:

$SecurePassword = Read-Host -AsSecureString  "Enter password" | convertfrom-securestring | out-file C:\Users\tmarsh\Documents\securePassword.txt
Run Code Online (Sandbox Code Playgroud)

我已经尝试了几种方法将其转换回来,但它们似乎都没有正常工作.最近,我尝试过以下内容:

$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
Run Code Online (Sandbox Code Playgroud)

这也给我一个错误.

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
Run Code Online (Sandbox Code Playgroud)

有谁知道一种适用于此的方法?

Mat*_*ewG 103

你很接近,但你传递给的参数SecureStringToBSTR必须是a SecureString.您似乎传递了ConvertFrom-SecureString的结果,这是一个加密的标准字符串.所以ConvertFrom-SecureString在传递之前请先调用它ConvertTo-SecureString.

$SecurePassword = ConvertTo-SecureString $PlainPassword
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
Run Code Online (Sandbox Code Playgroud)

  • 根据[Marshal.SecureStringToBSTR](https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.securestringtobstr(v = vs.110).aspx)文档:_因为此方法分配字符串所需的非托管内存,完成后通过调用ZeroFreeBSTR方法_总是释放BSTR.所以,你必须在最后执行以下内容:`[Runtime.InteropServices.Marshal] :: ZeroFreeBSTR($ BSTR)`. (13认同)
  • @Orangutech 您不能只将变量设置为 `$null`,因为这里我们正在处理非托管对象。您不会立即收到错误消息,但我认为随着时间的推移,您可能会遇到问题。 (3认同)
  • 如前所述,除了由于缺少对“ZeroFreeBSTR()”的调用而导致的内存泄漏之外,“PtrToStringAuto()”的使用在概念上始终存在缺陷,并且 - 现在 PowerShell 是跨平台的 - 在类 Unix 平台上失败。它应该始终是“PtrToStringBSTR()” - 请参阅[此答案](/sf/answers/4228487791/)。 (3认同)
  • 我很高兴它有效.小心你的字符串,现在,它是一个不安全的字符串变量,可能包含一些像密码一样重要的东西 - 它在你的进程内存中不再安全等等. (2认同)

Nic*_*lay 66

您也可以使用PSCredential.GetNetworkCredential():

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

  • 支持此解决方案,因为它更强大。 (5认同)
  • 较短:`[System.Net.NetworkCredential]::new("", $SecurePassword).Password` (3认同)
  • 较短:`[PSCredential]::new(0, $SecurePassword).GetNetworkCredential().Password` (2认同)

Mac*_*cke 26

在 PS 7 中,您可以使用ConvertFrom-SecureString-AsPlainText

#Requires -Version 7.0 

$UnsecurePassword = ConvertFrom-SecureString -SecureString $SecurePassword -AsPlainText
Run Code Online (Sandbox Code Playgroud)

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

ConvertFrom-SecureString
           [-SecureString] <SecureString>
           [-AsPlainText]
           [<CommonParameters>]
Run Code Online (Sandbox Code Playgroud)

  • 这让我发疯。我试图在 v5 中使用此语法但无济于事。 (6认同)
  • 使用“#Requires -Version 7.0”让脚本使用者获得正确的错误消息。来自 https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_requires#-version-nn (4认同)
  • 我已经被 PS7 宠坏了,以至于我忘记了我支持的大多数环境只有 PS5。“你说我不能这么做是什么意思——哦,对了。太新了。该死。” (3认同)

小智 11

在PowerShell中将其转换回最简单的方法

[System.Net.NetworkCredential]::new("", $SecurePassword).Password
Run Code Online (Sandbox Code Playgroud)

  • 确实,不需要经过 PSCredential。 (2认同)
  • @MikeLoux 然后只需使用 0(零)作为用户参数,它甚至比空字符串短,并且可以与两个构造函数一起使用:`(New-Object PSCredential 0,$SecureString).GetNetworkCredential().Password` 或 `(New -对象 System.Net.NetworkCredential 0,$SecureString).Password` (2认同)