本页目录
证书与 PKI
TLS 的安全基座——X.509 证书链、ACME 自动签发、OCSP/CRL 吊销检查、Certificate Transparency 公开审计。PKI 不是完美的(任何 CA 可以为任何域名签发证书),CT 和密钥固定是对这个信任模型的补丁。
概述
TLS 的信任基础是 X.509 证书和 PKI(Public Key Infrastructure)。浏览器/OS 预置了约 150 个 Root CA 证书——这些 CA 可以签发任何域名的证书,构成整个 HTTPS 信任体系的单点故障。Let's Encrypt(2016)通过 ACME 协议将证书签发自动化并完全免费,使 HTTPS 部署率从 40% 跃升到 90%+。Certificate Transparency(2013)强制所有证书记录在公开日志中,让恶意签发可被检测。OCSP Stapling 在保护隐私的同时实现吊销检查。
X.509 证书
Certificate:
tbsCertificate (to-be-signed):
Version: v3 (2)
Serial Number: 随机 (CA 防重)
Signature Algorithm: sha256WithRSAEncryption or ecdsa-with-SHA256
Issuer: C=US, O=Let's Encrypt, CN=R3 ← 谁签的
Validity:
Not Before: 2024-01-01T00:00:00Z
Not After: 2024-03-31T23:59:59Z (最大 90 days for LE)
Subject: CN=grafana.liz6.com ← 证书属于谁
Subject Public Key Info:
Algorithm: id-ecPublicKey (or rsaEncryption)
Public Key: (256-bit EC point or 2048-bit RSA modulus)
Extensions:
SAN (Subject Alternative Name): grafana.liz6.com, *.liz6.com ← 关键!
Basic Constraints: CA=FALSE ← 不是 CA (不能签发子证书)
Key Usage: Digital Signature, Key Encipherment
Extended Key Usage: TLS Web Server Authentication
CRL Distribution Points: http://r3.i.lencr.org/
Authority Information Access:
OCSP: http://r3.o.lencr.org/
CA Issuers: http://r3.i.lencr.org/
Certificate Policies
CT Precertificate SCTs (Signed Certificate Timestamps)
Signature Algorithm
Signature Value
SAN 的重要性
浏览器已完全忽略 CN (Common Name)。所有域名验证基于 SAN。如果证书没有包含访问的域名 → browser error: ERR_CERT_COMMON_NAME_INVALID:
SAN: DNS:grafana.liz6.com, DNS:*.liz6.com
→ 匹配 grafana.liz6.com ✓, chat.liz6.com ✓, grafana.liz6.com:8443 ✗ (SAN 不含端口)
→ 通配符: *.liz6.com 匹配单级子域 (chat.liz6.com) 但不匹配多级 (sub.chat.liz6.com)
Chain of Trust
Root CA (ISRG Root X1):
Subject = Issuer = 自己 (自签)
Basic Constraints: CA=TRUE
→ 预置在 OS/Browser trust store /etc/ssl/certs/
Intermediate CA (R3):
Subject: R3, Issuer: ISRG Root X1 → 由 Root 签发
Basic Constraints: CA=TRUE, pathLenConstraint=0 (不能再签发 CA)
Leaf (grafana.liz6.com):
Subject: grafana.liz6.com, Issuer: R3 → 由 Intermediate 签发
Basic Constraints: CA=FALSE
验证: 自下而上: leaf → R3 → Root → trust anchor (在 trust store 中)
ACME
客户端 (certbot/acme.sh) 通过 ACME v2 协议自动获取证书:
1. 创建 account: POST /acme/new-acct → account URL
2. 提交 order: POST /acme/new-order { identifiers: [grafana, *.liz6.com] }
→ order object + authorizations + challenges
3. 完成 challenges:
HTTP-01: http://domain/.well-known/acme-challenge/<token>
→ CA 验证 GET 返回 key authorization = token + "." + thumbprint
DNS-01: 放 TXT _acme-challenge.domain = key authorization
→ CA 验证 DNS (可签通配符!)
TLS-ALPN-01: 在 ALPN 中返回 key authorization
4. 等待 validation → CA 验证 challenge
5. Finalize: POST CSR → CA 签发证书
6. Download: certificate chain (PEM, ~3-5KB)
OCSP 与 Revocation
OCSP (Online Certificate Status Protocol):
Client: 问 CA "这个 serial number 的证书状态?"
CA: "good" / "revoked" / "unknown"
问题: CA 知道你在访问哪个网站 → 隐私 + 延迟 (额外 TLS 连接)
OCSP Stapling (RFC 6066, TLS Certificate Status Request extension):
Server: 定期从 CA 获取 OCSP response (签名过的) → 缓存在本端
TLS 握手: 在 CertificateStatus 消息中附带 OCSP response
Client: 验证 OCSP response 的签名 → 不需要单独请求 OCSP
→ 隐私 + 延迟优化
CRL (Certificate Revocation List):
定期发布的吊销证书列表 (整个 CA 范围内所有 revoked cert)
缺点: 大 (可能 MB), 更新不及时 (通常 24h)
OCSP 更实时 (but stapling needed for privacy)
Certificate Transparency
问题: 恶意的 CA (或被攻破的 CA) 签发 unauthorized 证书 → 中间人攻击
CT (RFC 6962):
所有 certificate 提交到公开的 CT logs:
→ SCT (Signed Certificate Timestamp): log 给证书的"收据"
→ 浏览器验证: 证书至少含 2 个 SCT (来自不同 log operators)
→ Monitor: 任何人都可以监控 CT logs → 发现 unauthorized issuance
你的证书: crt.sh/?domain=liz6.com → 查看所有 liz6.com 的证书历史
参考
- RFC: 5280, 8555, 6960, 6962, 7633 (CT for code signing)
- 工具:
openssl x509 -text -in cert.pem,crt.sh,certbot certificates
Keywords: X.509, SAN, chain of trust, ACME, Let's Encrypt, DNS-01, OCSP stapling, CRL, SCT, CT logs