导入凭据时,Import-Clixml中是否存在任何隐式假设? [英] Are there any implicit assumptions in Import-Clixml when importing credentials?

查看:123
本文介绍了导入凭据时,Import-Clixml中是否存在任何隐式假设?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道我是否有任何隐式假设可能会使代码出现故障?

I wonder if there are any implicit assumptions that I've taken that may make the code malfunction?

有一个原因我想避免使用Import-Clixml cmdlet? 因此,我开发了一种替代方法,即一系列命令,旨在从使用Export-Clixml创建的CliXml文件中提取用户名和密码. 现在它可以工作了,但是我不确定例如拆分解决方案是否可靠.

There is a reason I want to avoid using Import-Clixml cmdlet? Hence, I've developed an alternative, i.e. a sequence of command that is aimed to extract username and password from CliXml file created with Export-Clixml. It works by now but I'm not sure if for instance the splitting solution is reliable.

$credFileUriBld = [UriBuilder]::New('file','localhost',-1,"MyCredentials.xml")) 

$credFile = [Xml.XMLDocument]::New()

$nsMgr4ps1xml = [Xml.XmlNamespaceManager]::New($credFile.NameTable)
$nsMgr4ps1xml.AddNamespace('ps1xml','http://schemas.microsoft.com/powershell/2004/04')
$credFile.Load($credFileUriBld.Path)

$netCredInfo = [System.Net.NetworkCredential]::New($credFile.SelectSingleNode('/ps1xml:Objs/ps1xml:Obj/ps1xml:Props/ps1xml:S[@N=''UserName'']/text()',$nsMgr4ps1xml).Get_Value(),
                                                   ($credFile.SelectSingleNode('/ps1xml:Objs/ps1xml:Obj/ps1xml:Props/ps1xml:SS[@N=''Password'']/text()',$nsMgr4ps1xml).Get_Value().Split('00') | 
                                                    ForEach-Object { if([String]::IsNullOrEmpty($_)) { } else { $_.Trim() } } |
                                                    ForEach-Object { [convert]::ToInt32($_,16) } |
                                                    ForEach-Object { [convert]::ToChar($_) } |
                                                    ForEach-Object -Begin { $ss=[SecureString]::New() } -Process {$ss.AppendChar($_)} -End { $ss }))

$netCredInfo.UserName
$netCredInfo.Password

您能否瞥一眼并告知是否存在使代码不可靠的假设?

May you take a glimpse and advise if there are any assumptions that make the code unreliable?

推荐答案

您的方法<仅> em 在类Unix平台上的PowerShell Core 中工作(macOS,Linux),但是出于安全原因不应该在此使用 -它在Windows(在Windows PowerShell和PowerShell Core中均不起作用),因为那里的密码是-明智地-真正加密的,而您的代码假定未加密密码存储.

Your approach only works in PowerShell Core on Unix-like platforms (macOS, Linux), but it shouldn't be used there for security reasons - it doesn't work on Windows (neither in Windows PowerShell nor in PowerShell Core), because the passwords there are - sensibly - truly encrypted, whereas your code assumes non-encrypted password storage.

安全警告:

    在类似Unix的平台上,
  • [securestring]不提供任何保护-字符存储未加密 -仅在Windows上基于[securestring] 的加密依赖于仅Windows的 DPAPI (数据保护API).

  • [securestring] on Unix-like platforms offers NO protection - the characters are stored unencrypted - the encryption underlying [securestring] on Windows only relies on the Windows-only DPAPI (Data Protection API).

    一般不建议
  • [securestring] 用于新代码-请参见
  • [securestring] is generally not recommended for new code - see this Roslyn analyzer recommendation.

如果您在类似Unix的平台上通过Export-CliXml[securestring]实例保存到文件 ,例如使用Get-Credential | Export-CliXml MyCredentials.xml-可以读取文件的任何人都可以轻松检索安全"数据(密码).相反,在Windows上,存储了DPAPI加密的表示,只能由同一用户在同一台​​计算机上解密.

If you save a [securestring] instance to a file via Export-CliXml on a Unix-like platform - e.g. with Get-Credential | Export-CliXml MyCredentials.xml - the "secure" data (password) can trivially be retrieved by anyone who can read the file. By contrast, on Windows a DPAPI-encrypted representation is stored that can only be decrypted by the same user on the same machine.

  • 正如您的代码所示,在Unix上,持久化的[securestring]实例只是一个字节字符串",其中包含构成纯文本内容的字符的Unicode代码点;例如,包含字符串'test'[securestring]被持久保存为'7400650073007400',其构造如下:

  • As your code demonstrates, on Unix a persisted [securestring] instance is simply a "byte string" that contains the Unicode code points of the characters making up the plain-text content; for instance, a [securestring] containing string 'test' is persisted as '7400650073007400', which can be constructed as follows:

  • -join [Text.Encoding]::Unicode.GetBytes('test').ForEach({ $_.Tostring('x2') })

...并转换为:
[Text.Encoding]::Unicode.GetString([byte[]] ('7400650073007400' -split '(..)' -ne '' -replace '^', '0x'))

...and converted back with:
[Text.Encoding]::Unicode.GetString([byte[]] ('7400650073007400' -split '(..)' -ne '' -replace '^', '0x'))

简而言之:在类似Unix的平台(PowerShell Core )上,请勿使用Get-Credential | Export-CliXml保留凭据-它们将被未加密存储.要提供任何保护,您必须拒绝其他所有人通过文件权限对文件的读取访问权限.

In short: On Unix-like platforms (PowerShell Core), do NOT use Get-Credential | Export-CliXml to persist credentials - they will be stored UNENCRYPTED. To provide any protection at all you'd have to deny everyone else read access to the file via file permissions.

仅在Windows上使用 ,如果您确实需要避免

For use on Windows only, if you do need to avoid Import-CliXml, here's a greatly simplified solution that should also perform better.

尽管此代码在技术上 也可以在类似Unix的平台上工作,但如上所述,它没有提供任何保护.

While this code would technically also work on Unix-like platforms, it offers no protection whatsoever, as discussed above.

请注意,它需要使用 DPAPI 加密的密码表示形式加密为安全字符串([securestring]实例).

Do note that it requires the use of the ConvertTo-SecureString cmdlet in order to convert the DPAPI-encrypted password representation in the CLIXML file to a secure string ([securestring] instance).

# Load the CLIXML file into a [System.Xml.XmlDocument] ([xml]) instance.
($credXml = [xml]::new()).Load($PWD.ProviderPath + '\MyCredentials.xml')

# Take an XPath shortcut that avoids having to deal with namespaces.
# This should be safe, if you know your XML file to have been created with
#   Get-Credential | Export-CliXml MyCredentials.xml
$username, $encryptedPassword = 
  $credXml.SelectNodes('//*[@N="UserName" or @N="Password"]').'#text'

$networkCred = [System.Net.NetworkCredential]::new(
  $username, 
  (ConvertTo-SecureString $encryptedPassword)
)

$networkCred.UserName
# $networkCred.Password  # CAUTION: This would echo the plain-text password.

这篇关于导入凭据时,Import-Clixml中是否存在任何隐式假设?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆