Pha*_*ake 4 powershell .net-core
我没有成功让以下代码片段输出“Hello World!” 在 PS7
$string = $("Hello World!" | ConvertTo-SecureString -AsPlainText -Force)
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($string))
Run Code Online (Sandbox Code Playgroud)
上面的代码是一个不指定长度解密安全字符串的例子。
相同的代码适用于 PS6 和 PS5 以完全解密安全字符串,但不适用于 PS7。我发现解决这个问题的唯一方法是使用 PtrToStringBSTR。然后它可以在此用例的所有 PS 版本中按预期工作。
我在 Github 上的 Powershell 存储库中提出了一个问题,但没有任何回应。老实说,我只是想确认其他人的行为是否相同。
https://github.com/PowerShell/PowerShell/issues/11953
我认为对于许多移植到 PS7 的代码来说,这样的事情将是一个突破性的变化。
这是我迄今为止发现的:
文档
根据文档,指定整数时,PtrToStringAuto:
Allocates a managed String and copies the specified number of characters from a string stored in unmanaged memory into it.
指定 11 的 int 返回“Hello”,这是因为返回的所有其他字符都是 Null。在这种情况下,您必须指定一个 23 的 int 以返回完整的字符串“Hello World!” 使用这种方法。我已经将输出存储在一个变量中来演示这一点。
$String = $("Hello World!" | ConvertTo-SecureString -AsPlainText -Force)
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($string), 23)
$String[0] Returns H
$String[1] Returns NULL
$String[2] Returns E
$String[3] Returns NULL
etc....
Run Code Online (Sandbox Code Playgroud)
如果没有指定整数,PtrToStringAuto:
Allocates a managed String and copies all characters up to the first null character from a string stored in unmanaged memory into it.
我相信这表明安全字符串被存储为 NULL 值,而在 PS6 中它不是,或者 PtrToStringAuto 函数的行为已经改变,现在遵循上述文档描述的行为。
这只是 macOS 上的问题;但是,使用 PtrToStringBSTR 代替 PtrToStringAuto 来解密安全字符串可以在 Windows 和 macOS 上按预期工作。
这似乎相关:https : //stackoverflow.com/a/11022662/4257163
我也没有看到任何地方进行了更改。
请注意,[securestring]是不建议新的代码了。
虽然在 Windows 上安全字符串提供有限的保护- 通过将加密的字符串存储在内存中 - 通过DPAPI - 并通过缩短纯文本表示在内存中保存的窗口,但在类 Unix 平台上根本不使用加密。[1]
我发现解决此问题的唯一方法是使用
PtrToStringBSTR.
这不仅是一种围绕这个问题,PtrToStringBSTR是该方法应该被用来开始考虑到输入字符串是,BSTR。[2]
请注意,将安全字符串与常规[string]实例相互转换会破坏使用[securestring]开始的目的:您最终将在您无法控制的进程内存中获得敏感数据的纯文本表示。
如果你真的想这样做,一个更简单的、跨平台兼容的方法是:
[System.Net.NetworkCredential]::new('dummy', $string).Password
Run Code Online (Sandbox Code Playgroud)
[1] 当您通过或-将安全字符串保存在文件中时,这尤其成问题- 请参阅此答案。ConvertFrom-SecureStringExport-CliXml
[2] AutoinPtrToStringAuto()表示假定非托管输入字符串使用适合平台的字符编码,而BSTR在所有平台上都是“Unicode”(UTF-16) 字符串。在 Windows 上,假定非托管字符串具有 UTF-16 编码(这就是代码有效的原因),而在类 Unix 平台上,它是 UTF-8,因为 .NET Core 3.0(PowerShell [Core] 7.0 基于 .NET Core 3.1),它解释了您的症状:NUL字符。在BSTR实例的 UTF-16 代码单元中,当(错误)解释为 UTF-8 时,它们本身就被解释为字符。请注意,.NET Core 2.x(这是 PowerShell [Core] 6.x 所基于的)(不恰当地)默认为 UTF-16,这个 PR 修复了,相当于一个突破性的变化。
| 归档时间: |
|
| 查看次数: |
1011 次 |
| 最近记录: |