Windows 代码签名原理:Authenticode 与 SmartScreen 信誉
签名流程本身只有三步,真正复杂的却是它背后的另一套系统。这篇文章把 Authenticode 和 SmartScreen 拆开讲清楚——前者保证文件没被改过,后者 决定用户会不会看到那个蓝色弹窗。
签名时发生了什么
Windows 用的是微软自己的一套签名格式,叫 Authenticode。整个机制基于非对称加密,发布者这一侧只有三步:
- 对可执行文件计算 SHA-256 哈希;
- 用私钥加密这个哈希,得到的密文就是「数字签名」;
- 把签名块、证书、还有一个时间戳(向时间戳服务器请求的一份证明:此签名在某个时刻已存在)一起嵌入 PE 文件。
验证时发生了什么
用户电脑上这一步同样只有三步,但它是信任真正成立的地方:
- 重新计算文件哈希,用证书里的公钥解密签名块,比对两者是否一致——不一致说明文件被篡改过;
- 检查证书链能否回溯到 Windows 内置信任的根 CA;
- 检查时间戳——只要签名时证书有效,即使证书后来过期了,签名依然有效。
签名不等于「安全无毒」
签名只保证两件事:文件自签名后没被篡改过、发布者持有某个 CA 认证过的身份。一个恶意软件完全可以花钱买张 OV 证书签名后分发。证书管「身份可追溯」,不管「善恶」。
真正弹不弹窗,SmartScreen 说了算
Windows 8 之后引入的 SmartScreen 是一个基于信誉的系统,它的判断依据不是「有没有签名」,而是「这个证书 + 这个软件有多少信誉积累」。一张刚买的全新证书,哪怕完全合法,信誉也是零——用户运行时照样会看到蓝色拦截弹窗,只是发布者一栏从「未知发布者」变成了你的名字。
信誉主要靠三样东西慢慢养:证书/发布者的存在时间、软件的实际下载量、有没有被用户投诉举报。这也是为什么 EV 证书曾经值钱——它能立刻获得较高的初始信誉(不过 2023 年起各大 CA 已停止签发用于签名的 EV 证书,这条捷径已经没了)。
另外注意时间戳的作用:如果你签了名但没加时间戳,证书过期后所有历史安装包都会变成「签名无效」。所以签名流程里
signtool 的 /tr 参数不是可选项。
本文是《用 SignPath 给开源 Windows 应用免费做代码签名》的上半篇,下一篇讲怎么把签名接进 CI。