从PowerShell调用Get-AuthenticodeSignature的结果不一致,通常是NotSigned

p3rjfoxz  于 9个月前  发布在  Shell
关注(0)|答案(1)|浏览(116)

我有一些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


我已经花了一个星期的时间在这上面了,但是我还是不能理解是什么导致了这种差异/不一致。我必须让它工作,因为我的应用程序(“客户端”)从服务器(“服务器”)接收到字符串形式的脚本,并且必须验证内容的有效性。

cbjzeqam

cbjzeqam1#

**更新:**从pwsh 7.4.0开始,这个bug已经被修复(fix PR here)。但是,很多人会在一段时间内使用以前的版本,而5.1版仍然存在这个bug,所以下面的变通方法仍然很有价值。

遗憾的是,Get-AuthenticodeSignature -Content只识别表示“Unicode”(UTF-16 LE)编码字符的字节数组-任何其他编码在输出中都被错误地表示为NotSigned
请参见this GitHub issue
您的症状意味着只有CreateApplication.ps1UpdateParameters.ps1脚本是UTF-16 LE编码的。
如果要将-Content与所有脚本一起使用:

  • either:将所有脚本文件转码为UTF-16 LE(使用该编码保存它们)。
    • 或 *:将表达式([Text.Encoding]::Unicode.GetPreamble() +[Text.Encoding]::Unicode.GetBytes((Get-Content -Raw $_.FullName)))传递到-Content,即手动将文件内容转换为UTF-16 LE字节;请注意,需要显式地在BOM(前导码)前面加上前缀)。

正如您所观察到的,使用(隐含的)参数-FilePath-即传递 * 文件路径 * 并让Get-AuthenticodeSignature本身读取其 * 内容 * -* 不 * 受此编码限制-只要PowerShell可以根据通常的规则推断脚本文件的编码,签名验证就会成功。

相关问题