什么是证书透明度

证书透明度(Certificate Transparency,简称 CT)是 Google 提出的一个开源框架,旨在为 TLS 证书提供公开的审计和监控机制。它的核心目标是检测恶意或错误签发的证书,防止证书颁发机构(CA)未经授权签发证书。

在 CT 出现之前,如果某个 CA 被攻击或故意签发虚假证书,这些证书可能在很长时间内不被发现。CT 通过要求所有证书必须记录在公开的日志服务器上,使得任何人都可以审计证书签发行为。

CT 架构解析

证书透明度由三个核心组件构成:

1. 日志服务器(Log Server)

日志服务器是 CT 的核心,是一个仅追加(append-only)的 Merkle 树结构数据库。每个日志服务器接收并存储证书条目,主要特性:

  • 仅追加:一旦记录被添加,就不能删除或修改
  • Merkle 树:使用密码学哈希树结构,可以高效验证数据完整性
  • 公开可访问:任何人都可以提交证书或查询日志

主流的公开日志服务器包括:

  • Google Argon(ct.googleapis.com/pki/argon)
  • DigiCert Log(ct.digicert.com/log)
  • Let’s Encrypt(ct.letsencrypt.org)

2. 监控器(Monitor)

监控器定期检查日志服务器,查找可疑的证书签发行为。例如:

  • 为知名域名签发的异常证书
  • 仿冒知名网站的证书
  • 来自不可信 CA 的证书

常见的监控服务包括:

  • crt.sh - 免费证书搜索数据库
  • Google Monitor
  • Cloudflare Monitor

3. 审计员(Auditor)

审计员验证日志服务器的行为,确保它们:

  • 正确记录了所有提交的证书
  • 没有作弊或隐瞒记录
  • 响应一致的查询

浏览器通常内置审计员功能,在验证证书时自动检查 SCT。

SCT:签名证书时间戳

当证书被提交到 CT 日志时,日志服务器会返回 Signed Certificate Timestamp(SCT)。SCT 包含:

  • 日志服务器 ID:签发 SCT 的日志服务器标识
  • 序列号:该证书在日志中的唯一编号
  • 时间戳:证书被记录的时间
  • 签名:日志服务器对上述信息的数字签名

浏览器在验证 TLS 连接时,会检查证书是否附带有效的 SCT。根据浏览器策略,通常要求至少 1-2 个 SCT 才能完全信任证书。

SCT 的传输方式

SCT 可以通过三种方式传递给浏览器:

  1. X.509 扩展:证书本身包含 signedCertificateTimestampList 扩展
  2. TLS 扩展:在 TLS 握手期间通过 signed_certificate_timestamp 扩展传输
  3. OCSP 响应:通过 OCSP 响应中的 signedCertificateTimestampList 扩展

CT 对 CA 的要求

主流浏览器对 CT 有明确要求:

CA 类型 SCT 要求
根 CA 无要求
预置根 CA 至少 2 个 SCT(来自不同日志服务器)
独立 CA 至少 1 个 SCT

自 2018 年起,Google Chrome 要求所有公开信任的证书都必须记录在 CT 日志中。

验证证书的 CT 记录

方法一:使用 crt.sh 查询

访问 crt.sh,输入域名即可查询该域名的所有 CT 记录:

1
2
# 使用 curl 查询 crt.sh
curl -s "https://crt.sh/?q=example.com&output=json" | jq '.[].common_name'

方法二:使用 OpenSSL 查看证书扩展

从证书中提取 CT 扩展信息:

1
2
3
# 获取证书并查看 CT 扩展
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \
    openssl x509 -noout -text | grep -A5 "1.3.6.1.4.1.11129.2.4.4"

1.3.6.1.4.1.11129.2.4.4 是 SCT 扩展的 OID。

方法三:使用 OpenSSL s_client 请求 SCT

现代 OpenSSL 支持在 TLS 握手时请求 SCT:

1
2
3
# 连接并请求 SCT
echo | openssl s_client -connect example.com:443 -ct \
    -showcerts 2>&1 | grep -i "sct"

方法四:使用 ct_log_verify 工具

1
2
# 验证证书是否被正确记录到 CT 日志
ct_logverify -cert certificate.pem -ct_log_pubkey log_pubkey.pem

CT 日志服务器列表

要查看浏览器信任的 CT 日志服务器列表,可以参考 Google Chrome 的 CT 策略文档

也可以从 Google 官方获取最新的日志列表:

1
2
# 获取 Google 维护的 CT 日志列表
curl -s "https://www.gstatic.com/ct/log_list/v3/log_list.json" | jq '.logs[].log_id'

CT 的局限性

虽然 CT 大大提升了证书安全性,但仍有一些局限:

  1. 仅检测,无法阻止:CT 可以检测恶意证书,但无法阻止 CA 签发
  2. 日志服务器信任:浏览器必须预先信任特定的日志服务器
  3. 隐私考量:所有证书都公开记录,可能暴露域名遍历行为
  4. 部署复杂性:CA 需要将证书提交到多个日志,增加运营成本

总结

证书透明度是现代 PKI 安全的重要补充。通过公开的日志机制,任何人都可以审计证书签发行为,及时发现异常。主流浏览器已全面支持 CT,在选择证书时,确保 CA 正确配置了 CT 记录是保障网站安全的关键步骤。


参考来源