我有一些PowerShell文件的代码在构建过程中签署。
根据调用Get-AuthenticodeSignature
的方式,我会得到不同的签名状态:
PS> Get-ChildItem | ForEach { Get-AuthenticodeSignature $_.Name }
SignerCertificate Status Path
----------------- ------ ----
E36170335E3DD78B6CDF1594B0D164F7C8A7B324 Valid CleanUpdateParameters.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324 Valid CreateApplication.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324 Valid DeleteApplication.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324 Valid ProvisionApplicationType.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324 Valid UnprovisionApplicationType.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324 Valid UpdateParameters.ps1
字符串
一切看起来都很好。但是当我尝试使用二进制内容验证文件时,结果如下:
PS> Get-ChildItem | ForEach { Get-AuthenticodeSignature -Content ([System.IO.File]::ReadAllBytes($_.FullName)) -SourcePathOrExtension $_.Name }
SignerCertificate Status Path
----------------- ------ ----
NotSigned CleanUpdateParameters.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324 Valid CreateApplication.ps1
NotSigned DeleteApplication.ps1
NotSigned ProvisionApplicationType.ps1
NotSigned UnprovisionApplicationType.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324 Valid UpdateParameters.ps1
型
或字符串内容:
PS> Get-ChildItem | ForEach { Get-AuthenticodeSignature -Content ([System.Text.Encoding]::ASCII.GetBytes([System.IO.File]::ReadAllText($_.FullName))) -SourcePathOrExtension $_.Name }
SignerCertificate Status Path
----------------- ------ ----
NotSigned CleanUpdateParameters.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324 Valid CreateApplication.ps1
NotSigned DeleteApplication.ps1
NotSigned ProvisionApplicationType.ps1
NotSigned UnprovisionApplicationType.ps1
E36170335E3DD78B6CDF1594B0D164F7C8A7B324 Valid UpdateParameters.ps1
型
我已经花了一个星期的时间在这上面了,但是我还是不能理解是什么导致了这种差异/不一致。我必须让它工作,因为我的应用程序(“客户端”)从服务器(“服务器”)接收到字符串形式的脚本,并且必须验证内容的有效性。
1条答案
按热度按时间cbjzeqam1#
**更新:**从pwsh 7.4.0开始,这个bug已经被修复(fix PR here)。但是,很多人会在一段时间内使用以前的版本,而5.1版仍然存在这个bug,所以下面的变通方法仍然很有价值。
遗憾的是,
Get-AuthenticodeSignature -Content
只识别表示“Unicode”(UTF-16 LE)编码字符的字节数组-任何其他编码在输出中都被错误地表示为NotSigned
。请参见this GitHub issue。
您的症状意味着只有
CreateApplication.ps1
和UpdateParameters.ps1
脚本是UTF-16 LE编码的。如果要将
-Content
与所有脚本一起使用:([Text.Encoding]::Unicode.GetPreamble() +[Text.Encoding]::Unicode.GetBytes((Get-Content -Raw $_.FullName)))
传递到-Content
,即手动将文件内容转换为UTF-16 LE字节;请注意,需要显式地在BOM(前导码)前面加上前缀)。正如您所观察到的,使用(隐含的)参数
-FilePath
-即传递 * 文件路径 * 并让Get-AuthenticodeSignature
本身读取其 * 内容 * -* 不 * 受此编码限制-只要PowerShell可以根据通常的规则推断脚本文件的编码,签名验证就会成功。