PowerShell是Windows下验证证书链最直接可控的工具,基于系统原生CNG和.NET证书库;用Get-AuthenticodeSignature查签名有效性,再用X509Chain手动验证链完整性,结合signtool做深度交叉验证。
powershell 是 windows 环境下验证证书链最直接、最可控的工具,无需额外安装第三方软件,所有操作基于系统原生加密模块(cng)和 .net 证书类库,结果与系统信任策略完全一致。
用 Get-AuthenticodeSignature 快速判断签名有效性
这是最常用的第一步检查,适用于 exe、dll、ps1、msi 等支持 Authenticode 的文件:
- 运行
Get-AuthenticodeSignature -FilePath "C:\app\setup.exe" - 重点看 Status 字段:只有
Valid才表示签名本身未被篡改 - 同时检查 SignerCertificate 是否有值;若为
Null,说明文件未签名或签名已损坏 - 注意 TimeStamperCertificate 是否存在——没有时间戳的签名在证书过期后将无法验证
手动构建并验证证书链完整性
Get-AuthenticodeSignature 不会自动报告中间证书缺失或吊销问题,需主动调用 .NET 链式验证:
- 先获取签名对象:
$sig = Get-AuthenticodeSignature -FilePath "script.ps1" - 创建证书链并验证:
$chain = [System.Security.Cryptography.X509Certificates.X509Chain]::new(); $chain.Build($sig.SignerCertificate) - 检查结果:
$chain.ChainStatus返回空数组才代表链完整、无吊销、时间有效 - 若返回非空,每项含 Status 和 StatusInformation,例如
UntrustedRoot表示根证书不在本地受信任存储中
定位并检查证书存储中的对应证书
签名证书必须存在于系统的可信位置(如 Cert:\LocalMachine\Root 或 Cert:\CurrentUser\TrustedPublisher),否则即使链完整也会被系统拒绝:
- 用证书指纹快速查找:
Get-ChildItem Cert:\ -Recurse | Where-Object {$_.Thumbprint -eq $sig.SignerCertificate.Thumbprint} - 确认其所在存储路径是否属于系统信任范围(如 My、Root、TrustedPublisher)
- 若证书在 Cert:\CurrentUser\My 但执行策略为 AllSigned,可能因作用域不匹配导致脚本被拦截
- 导出证书供离线分析:
Export-Certificate -Cert $sig.SignerCertificate -FilePath "signer.cer"
结合 signtool 做深度交叉验证
PowerShell 提供的是基础链式校验,而 signtool(来自 Windows SDK 或 Visual Studio)能补充时间戳服务、交叉证书、策略匹配等细节:
- 验证带详细策略:
signtool verify /v /pa "file.exe"—— 检查是否符合 Windows 默认签名策略 - 强制验证时间戳链:
signtool verify /v /kp "file.exe"—— 确保时间戳证书自身也在有效信任链中 - 回溯签名时间:
signtool verify /v /t "file.exe"可显示签名时证书是否已在有效期 - 输出中出现
Successfully verified且无 warning,才代表全链可信


















