如果未提供,我正在使用 Powershell 根據另一個答案向用戶請求密碼。然后我將密碼(不是雙關語)傳遞給某個程式,do-something.exe. 我沒有使用中間變數,而是嘗試將密碼轉換為普通字串“行內”:
[CmdletBinding()]
Param(
[Parameter(Mandatory, HelpMessage="password?")] [SecureString]$password
)
do-something password=${[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))}
那是行不通的。我只能使用一個臨時的中間變數讓它作業:
[CmdletBinding()]
Param(
[Parameter(Mandatory, HelpMessage="password?")] [SecureString]$password
)
$pwd=[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))
do-something.exe password=$pwd
我在呼叫時嘗試評估行內密碼是否犯了錯誤do-something.exe?如何才能做到這一點?
uj5u.com熱心網友回復:
${...}是一個變數參考,任何...內容都被逐字作為變數名。
{...}通常不需要包含變數名稱,但在兩種情況下需要:(a) 如果變數名稱包含特殊字符和/或 (b) 在可擴展字串 ("...") 的背景關系中,以消除變數名稱與后續變數名稱的歧義字符 - 看到這個答案
為了將運算式或命令作為引數的一部分嵌入,請使用$(...)子運算式運算子,并最好將整個引數括起來"..."- 這樣,整個引數將作為單個引數明確傳遞,而以 a開頭的未參考標記子運算式將作為(至少)兩個引數傳遞(參見這個答案)。$(...)
- 如果運算式或命令本身構成引數,
(...)則分組運算子就足夠了,通常更可取 - 請參閱此答案
所以:
[CmdletBinding()]
param(
[Parameter(Mandatory, HelpMessage="password?")]
[SecureString] $password
)
# Note the use of $(...) and the enclosure of the whole argument in "..."
do-something "password=$([Runtime.InteropServices.Marshal]::PtrToStringBSTR([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)))"
另請注意:
在 Windows 上它沒有什么區別(在 Unix
[securestring]實體上幾乎不提供任何保護,應該完全避免),但它應該是[Runtime.InteropServices.Marshal]::PtrToStringBSTR(),而不是[Runtime.InteropServices.Marshal]::PtrToStringAuto()正如Santiago Squarzon指出的那樣,有一種更簡單的方法可以將
SecureString實體轉換為其純文本等效項(但是,通常應該避免使用[1],并且更根本的是,[securestring]不鼓勵在新專案中使用[2]):[pscredential]::new('unused', $password).GetNetworkCredential().Password
[1] 存盤在 .NET 字串中的密碼的純文本表示會在記憶體中停留一段您無法控制的未指定時間。更具體地說,如果它是process command line的一部分,就像你的情況一樣,它可以通過這種方式被發現。當然,如果您所針對的 CLI 除了使用純文本密碼之外無法進行身份驗證,那么您別無選擇。
[2] 請參閱此答案,該答案鏈接到此 .NET 平臺兼容性建議。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/521968.html
標籤:电源外壳密码插值
