You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Windows上验证Azure Trusted Signing签名的MSI安装包

自动更新场景下Azure Trusted Signing签名验证的推荐方案

核心验证逻辑基础

Azure Trusted Signing的核心特点是证书自动轮换,因此不能依赖固定证书指纹做验证,需转向基于证书属性和链信任的验证逻辑。Get-AuthenticodeSignature是Windows原生的可靠工具,其返回的Valid状态已经包含了基础的证书链验证、根CA信任检查,但仍需补充针对性的属性校验。

必须执行的关键检查项

1. 签名状态验证

首先确保Get-AuthenticodeSignature返回的Status字段为Valid,这是最基础的验证:

  • 该状态意味着证书链完整且受Windows信任(根CA在系统受信任根存储中)
  • 默认包含证书吊销检查(可通过参数调整,但不建议关闭)

2. 颁发者与主题验证

Azure Trusted Signing的签名证书由微软固定的CA颁发,且主题会关联你的Trusted Signing账户/池信息:

  • 颁发者通常为CN=Microsoft Azure Code Signing PCA 2021, O=Microsoft Corporation, L=Redmond, S=Washington, C=US(可从Azure Portal的Trusted Signing配置中确认)
  • 主题需匹配你创建的Trusted Signing账户或签名池的标识,比如CN=Your_Trusted_Signing_Pool_Name
  • 这两个值是相对固定的(除非微软更新根CA),可硬编码到验证逻辑中

3. EKU(增强型密钥用法)验证

必须确认证书包含代码签名EKU(OID: 1.3.6.1.5.5.7.3.3),防止攻击者用其他用途的微软证书伪造签名:

  • 只有具备该EKU的证书,才被允许用于代码签名场景
  • 通过SignerCertificate.EnhancedKeyUsageList可获取证书的EKU列表

4. 强制证书链验证

虽然Get-AuthenticodeSignature默认会执行链验证,但程序化实现时需确保未绕过该环节:

  • 若使用PowerShell,无需额外参数,Status为Valid即代表链验证通过
  • 若使用原生API(如WinVerifyTrust),需指定正确的验证策略(WINTRUST_ACTION_GENERIC_VERIFY_V2),确保启用完整的链校验

程序化实现方案

方案1:PowerShell脚本集成(快速落地)

适合快速实现验证逻辑,可直接在应用中调用PowerShell脚本:

$msiPath = "C:\path\to\binary.msi"
$signature = Get-AuthenticodeSignature -FilePath $msiPath

# 检查签名基础状态
if ($signature.Status -ne 'Valid') {
    Write-Error "签名验证失败: $($signature.StatusMessage)"
    exit 1
}

# 验证颁发者(替换为你的Trusted Signing对应的CA)
$expectedIssuer = "CN=Microsoft Azure Code Signing PCA 2021, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
if ($signature.SignerCertificate.Issuer -ne $expectedIssuer) {
    Write-Error "颁发者不匹配: 预期[$expectedIssuer],实际[$($signature.SignerCertificate.Issuer)]"
    exit 1
}

# 验证主题(替换为你的Trusted Signing账户/池名称)
$expectedSubject = "CN=Your_Trusted_Signing_Pool_Name"
if ($signature.SignerCertificate.Subject -ne $expectedSubject) {
    Write-Error "主题不匹配: 预期[$expectedSubject],实际[$($signature.SignerCertificate.Subject)]"
    exit 1
}

# 验证代码签名EKU
$codeSigningOid = "1.3.6.1.5.5.7.3.3"
$hasValidEku = $signature.SignerCertificate.EnhancedKeyUsageList | Where-Object { $_.Oid.Value -eq $codeSigningOid }
if (-not $hasValidEku) {
    Write-Error "证书不具备代码签名权限"
    exit 1
}

Write-Host "MSI签名验证通过"

方案2:原生API调用(应用内集成)

若需在Rust等应用中直接实现,可调用Windows原生的WinVerifyTrust API:

  • 使用winapi或windows crate构造WINTRUST_DATA结构,指定验证对象为MSI文件路径
  • 验证策略选择WINTRUST_ACTION_GENERIC_VERIFY_V2,确保启用完整的链验证
  • 调用成功即代表签名有效,失败则返回具体错误码(如链不完整、证书吊销等)

关键注意事项

  • 禁止硬编码证书指纹:Azure Trusted Signing会定期轮换证书,硬编码指纹会导致后续更新验证失败
  • 保持系统根证书更新:Windows自动更新会维护受信任根证书,离线环境需手动导入微软的根CA,否则链验证会失败
  • 不要关闭吊销检查:吊销检查可防止已泄露或过期的证书被滥用,仅在极端离线场景下可考虑临时关闭

内容的提问来源于stack exchange,提问作者Pinabile

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 23:53:20