从 PowerShell 调用 Get-AuthenticodeSignature 的结果不一致,通常说 NotSigned
Inconsistency in results of calling Get-AuthenticodeSignature from PowerShell, often says NotSigned
我在构建期间对许多 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
我已经花了一个星期的时间来解决这个问题,无法理解是什么导致了这个 discrepancy/inconsistency。我必须让它工作,因为我的应用程序 ('client') 从服务 ('server') 接收脚本作为字符串,并且必须验证内容的有效性。
遗憾的是,Get-AuthenticodeSignature -Content
只能识别表示 "Unicode" (UTF-16LE) 编码字符的字节数组 - 任何其他编码都被错误表示为 NotSigned
在输出中。
参见 this GitHub issue。
您的症状表明只有脚本 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
本身读取其 contents - 不受此编码限制 - 只要 PowerShell 可以按照通常的规则推断脚本文件的编码,签名验证就会成功。
我在构建期间对许多 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
我已经花了一个星期的时间来解决这个问题,无法理解是什么导致了这个 discrepancy/inconsistency。我必须让它工作,因为我的应用程序 ('client') 从服务 ('server') 接收脚本作为字符串,并且必须验证内容的有效性。
遗憾的是,Get-AuthenticodeSignature -Content
只能识别表示 "Unicode" (UTF-16LE) 编码字符的字节数组 - 任何其他编码都被错误表示为 NotSigned
在输出中。
参见 this GitHub issue。
您的症状表明只有脚本 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
本身读取其 contents - 不受此编码限制 - 只要 PowerShell 可以按照通常的规则推断脚本文件的编码,签名验证就会成功。