我在构建期间签署了许多Power
Shell文件代码.
根据我调用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
我已经花了一个星期的时间,并且无法解决导致这种差异/不一致的问题.我必须让它工作,因为我的应用程序(‘客户端’)从服务(‘服务器’)接收脚本作为字符串,并且必须验证内容的有效性.
最佳答案 遗憾的是,如果字节数组表示“Unicode”(UTF-16LE)编码字符,则Get-AuthenticodeSignature -Content仅识别字节数组 – 任何其他编码在输出中被错误表示为NotSigned.
您的症状的含义是只有脚本CreateApplication.ps1和UpdateParameters.ps1是UTF-16LE编码的.
如果您想对所有脚本使用-Content:
>要么:将所有脚本文件转码为UTF-16LE(使用该编码保存).
>或:将表达式([Text.Encoding] :: Unicode.GetPreamble()[Text.Encoding] :: Unicode.GetBytes((Get-Content -Raw $_.FullName)))传递给-Content,即手动转换文件内容为UTF-16LE字节;请注意需要明确添加BOM(前导码)).
正如您所观察到的,使用(隐含)参数-FilePath – 即传递文件路径并让Get-AuthenticodeSignature本身读取其内容 – 不受此编码限制 – 只要PowerShell可以按常规推断脚本文件的编码规则,签名验证成功.