证书指纹有什么用

工具相关 ·

解析一张 SSL 证书时,结果里会列出两串很长的十六进制字符,分别标着「SHA-1 指纹」和「SHA-256 指纹」。它们看起来像哈希值,也确实就是哈希值——是对整张证书计算出来的摘要。指纹的用途很明确:确认「两张证书是不是同一张」。但要注意,它不能证明证书可信。

指纹是怎么算出来的

指纹是对整张证书的二进制内容(DER 编码)计算哈希得到的结果。

证书在文件里可能是 PEM 文本格式(Base64 加 BEGIN/END 行),也可能直接是 DER 二进制格式。但计算指纹时,会先把内容还原成 DER 二进制,再对它算哈希。

所以只要证书内容有一个字节的差异,指纹就会完全不同。这些差异可能包括:有效期变了、SAN 列表加了一个域名、序列号不同、签名算法不同。

SHA-1 指纹是 20 字节,用十六进制表示是 40 个字符。SHA-256 指纹是 32 字节,十六进制表示是 64 个字符。有些工具会把它们按两位一组用冒号分隔显示,便于阅读和比对。

用途一:比对两张证书

最直接的用途是判断「从两个渠道拿到的证书是不是同一张」。

比如运维同学从服务器上导出了一张证书,从 CDN 控制台下载了另一张,怀疑它们是否一致。计算两边的指纹,一致就说明是同一张,不一致说明有差异。

这个方法比逐字段比对更可靠,因为逐字段比对容易漏掉细节——比如 SAN 列表里多了一个域名,人工比对时可能没注意到,但指纹会立刻反映出来。

用途二:核对安装是否正确

有些服务会公布证书的指纹,用来让用户确认自己安装的是正确的证书。

例如在配置 VPN、邮件客户端、内部服务时,服务方可能提供一个指纹值,用户安装完证书后计算指纹并比对。这样可以避免中间人攻击——如果攻击者替换了证书,指纹就会不同。

在一些需要手工导入证书的场景(比如企业内网的自签名证书),指纹核对是一个必要的步骤。

指纹不是签名

这里需要明确一个关键区别:指纹不是签名。

指纹只能说明「这张证书是这一张」,它不能说明「这张证书是可信的」。

原因在于,任何人都可以给任意一张证书算指纹。攻击者自己生成一张证书,也能算出它的指纹,甚至可以把这张假证书的指纹公布出来。如果用户只是比对「指纹是否一致」,而指纹的来源本身不可信,那么比对就失去了意义。

签名的机制不同。证书里的签名是由 CA 的私钥生成的,验证签名需要用 CA 的公钥。攻击者没有 CA 的私钥,无法伪造签名。所以签名能证明「这张证书确实是由某个 CA 签发的」,这是指纹做不到的。

在实践中,指纹用于「核对」,签名用于「信任」。两者的作用不能互换。

SHA-1 和 SHA-256 该看哪个

两个指纹都列出来了,日常应该用哪个?

答案是 SHA-256。

原因和前面讨论过的一样:SHA-1 已经被实际构造出碰撞。2017 年 Google 和 CWI 联合发布了 SHAttered 攻击,构造出两个内容不同但 SHA-1 相同的 PDF 文件。这意味着 SHA-1 指纹理论上可能无法唯一标识一张证书——攻击者可以构造两张证书让它们有相同的 SHA-1 指纹。

虽然针对证书的实际碰撞攻击需要更苛刻的条件,但既然 SHA-256 没有这个问题,就没有理由继续依赖 SHA-1。

SHA-1 指纹仍然会显示,主要出于兼容性考虑——一些老旧的系统、文档、工单模板可能只记录 SHA-1 指纹。在核对这类历史记录时可以参考,但新记录应该使用 SHA-256。

指纹还能做什么

除了上面两个用途,指纹在运维里还有一些辅助作用。

排查证书更新是否生效。更新证书后,指纹应该变化。如果发现指纹没变,说明新的证书没有真正生效(可能配置文件路径不对、或者服务没重载)。

记录变更审计。在安全审计里记录每个时间点的证书指纹,可以清晰地看出证书何时被更换过。

区分同名证书。如果同一个域名有多张证书(比如测试环境和生产环境各一张),用指纹可以快速区分,比看有效期更可靠。

检查清单

  • 指纹是对整张证书的 DER 二进制内容计算哈希得到的摘要
  • 用途是比对两张证书是否相同、核对安装是否正确
  • 指纹不是签名,不能证明证书可信,只用于核对
  • 日常应使用 SHA-256 指纹,SHA-1 已被构造出碰撞
  • SHA-1 指纹仅用于兼容老旧系统与历史记录
  • 证书更新后指纹应当变化,可用于排查更新是否生效
阅读 14