代码之家  ›  专栏  ›  技术社区  ›  leeand00

为什么在存储安全字符串时要这样做?

  •  1
  • leeand00  · 技术社区  · 6 年前

    这会在某种程度上使它比仅仅是一个安全字符串并将其存储在凭证中更安全吗?为什么会有人这么做?

    $secVal = read-host  -AsSecureString -prompt "Enter xstoreuser password"
    $strVal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secVal)
    $dasPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($strVal)
    

    然后后来

    psftp -l somelogin -pw $dasPassword -P 22 -b .\ftp.txt somehost
    
    1 回复  |  直到 6 年前
        1
  •  4
  •   mklement0    6 年前

    你展示的技巧是 关于发出命令 更多 安全- 相反地 :

    您需要做额外的工作来从 [securestring] 例如,因为 为了将密码传递给 外部程序 psftp.exe 你需要一个 不安全的 纯文本 表示,因为外部程序对.NET安全字符串一无所知 .

    How secure is SecureString? 告诉您.NET安全字符串及其一般限制。


    作为旁白:提取纯文本密码的命令可以通过aux稍微简化一点。 [pscredential] 实例:

    # Returns the plain-text content of secure string $secVal:
    (New-Object pscredential somelogin, $secVal).GetNetworkCredential().Password
    

    这个 唯一安全的方法 是为了 完全避免纯文本密码 使用A PKI 方法 (基于公钥和私钥)相反,如果目标程序支持的话。


    证明 纯文本方法是 不安全的 (即使不使用中间变量来存储未加密的密码):

    # Create a [pscredential] instance with a secure-string password:
    # Note: To make this demo self-contained, I'm converting *from* plain
    #       text in order to construct the credential object.
    #       Note that you should never do that in production code.
    #       The need to specify -Force to do it is a reminder that it
    #       normally shouldn't be done.
    $cred = New-Object pscredential someuser,
              (ConvertTo-SecureString -AsPlainText -Force 'actualPassword')
    
    # Open a new hidden window that passes the password *as plain text* to 
    # `cmd /c echo` (and then waits for a keypress, to keep the process alive).
    $ps = Start-Process -PassThru -WindowStyle Hidden cmd "/c echo $($cred.GetNetworkCredential().Password) & pause"
    
    # Now inspect the process' command line using CIM (WMI):
    (Get-CimInstance Win32_Process -Filter "ProcessID = $($ps.ID)").CommandLine
    
    # Kill (stop) the sample process.
    $ps | Stop-Process
    

    上述收益率 "C:\WINDOWS\system32\cmd.exe" /c echo actualPassword & pause ,说明纯文本密码确实可以通过其他进程获得。

    您也可以使用 图形用户界面方法 用于检查正在运行的进程的命令行 :任务管理器( Taskmgr.exe )或者,如果没有潜在的截断, SysInternals' Process Explorer ( procexp.exe ) 但是,必须按需安装-请参见 this ServerFault answer .