浏览器验证证书
在TCP握手成功后进行TSL握手,在服务器的Server Hello的过程中会返回给客户端数字证书。
浏览器验证证书的合法性是一个多步骤的过程,涉及 证书链验证、签名校验、有效期检查、域名匹配 等关键环节。以下是详细的验证流程:
1. 证书链验证(Chain of Trust)
浏览器需要确认证书是由 受信任的根CA(Root CA) 签发的,而不是伪造的。验证步骤如下:
(1) 获取证书链
- 服务器在TLS握手时会发送:
- 站点证书(Leaf Certificate):当前网站的证书。
- 中间证书(Intermediate Certificates):链接到根CA的中间CA证书。
- 根证书(Root CA Certificate):已预装在操作系统/浏览器的信任存储中(如DigiCert、Let’s Encrypt的根证书)。
(2) 构建证书链
浏览器尝试构建一条从 站点证书 → 中间证书 → 根证书 的完整信任链。
示例:
站点证书(example.com) ↓ 由中间CA签发
中间证书(R3, Let's Encrypt) ↓ 由根CA签发
根证书(ISRG Root X1) # 预装在浏览器中
(3) 验证链的完整性
- 检查每一级证书的 签名 是否由上一级CA的私钥签发:
- 用 中间CA的公钥 验证站点证书的签名。
- 用 根CA的公钥 验证中间证书的签名。
- 如果任何一级签名验证失败,证书被视为非法。
2. 证书有效性检查
(1) 有效期验证
- 检查证书的 Not Before 和 Not After 时间戳,确保证书在有效期内。
- 过期证书 会触发浏览器警告(如
NET::ERR_CERT_DATE_INVALID
)。
(2) 域名匹配(Subject Alternative Name, SAN)
- 检查证书中的 Common Name (CN) 或 SAN(Subject Alternative Name) 是否与当前访问的域名完全匹配。
- 不匹配的示例:
- 证书为
*.example.com
,但访问的是test.example.org
→ 触发NET::ERR_CERT_COMMON_NAME_INVALID
。
- 证书为
(3) 密钥用途(Key Usage)
- 确保证书的扩展字段包含 TLS Web服务器认证(如
Extended Key Usage: serverAuth
)。 - 如果证书被误用于代码签名或邮件加密,浏览器会拒绝。
3. 吊销状态检查(Revocation Check)
即使证书是合法的,也可能因私钥泄露等原因被CA吊销。浏览器会检查:
(1) CRL(证书吊销列表)
- 从CA下载吊销列表(CRL文件),检查证书序列号是否在其中。
- 缺点:CRL文件可能较大且更新延迟。
(2) OCSP(在线证书状态协议)
- 浏览器向CA的OCSP服务器发送查询请求,实时检查证书状态。
- 示例请求:
GET /ocsp?serial=1234 HTTP/1.1 Host: ocsp.digicert.com
- 响应:
good
:证书有效。revoked
:证书已吊销(触发警告)。
(3) OCSP Stapling(优化性能)
- 服务器在TLS握手时直接提供OCSP响应(由CA预先签名),减少浏览器单独查询的开销。
4. 其他安全策略
(1) HSTS(HTTP严格传输安全)
- 如果网站响应头包含
Strict-Transport-Security
,浏览器会强制使用HTTPS,阻止证书错误页面的绕过。
(2) 证书透明度(Certificate Transparency, CT)
- 检查证书是否被记录在公共CT日志(如Google的CT项目)中,防止CA误签发或恶意签发。
(3) 证书钉扎(Certificate Pinning)
- 浏览器或应用预先存储合法证书的指纹(如SHA-256),仅接受匹配的证书(现已较少使用,改用CT)。
浏览器验证流程图
1. 接收证书链(站点证书 + 中间证书)│├─ 证书链验证(签名逐级校验)│ ├─ 站点证书 ← 中间CA公钥│ └─ 中间证书 ← 根CA公钥│├─ 有效期检查(Not Before/After)│├─ 域名匹配(CN/SAN)│├─ 吊销检查(OCSP/CRL)│└─ 其他策略(HSTS、CT等)
常见错误及原因
浏览器错误提示 | 可能原因 |
---|---|
NET::ERR_CERT_AUTHORITY_INVALID | 证书链不完整或根CA不受信任。 |
NET::ERR_CERT_DATE_INVALID | 证书过期或系统时间错误。 |
NET::ERR_CERT_REVOKED | 证书已被CA吊销。 |
NET::ERR_CERT_COMMON_NAME_INVALID | 证书域名与访问的URL不匹配。 |
如何手动检查证书?
1. 浏览器开发者工具
- Chrome/Firefox:按
F12
→ Security → View Certificate。
2. OpenSSL命令
openssl s_client -connect example.com:443 -servername example.com | openssl x509 -noout -text
检查输出中的:
Issuer
(颁发者)Validity
(有效期)Subject Alternative Name
(域名)X509v3 CRL Distribution Points
(吊销列表URL)
总结
浏览器通过 证书链验证、签名校验、吊销检查、域名匹配 等多重机制确保HTTPS证书的合法性。任何一环失败都会触发安全警告。开发者需确保证书配置正确,并定期更新以避免中断。
在数字证书的签发过程中,CA(证书颁发机构)实际上是对证书数据的哈希值进行签名,而非直接对原始内容签名。这一设计基于效率和安全的权衡。以下是详细解释:
1. 证书签名的核心流程
-
生成证书内容
CA首先构建证书的原始数据(包括公钥、颁发者、有效期、域名等信息),格式遵循X.509标准。 -
计算哈希值
- 对证书的**原始数据(不含签名字段本身)**计算哈希值(如SHA-256)。
- 为什么用哈希?
- 哈希将任意长度的数据固定为短摘要(如256位),减少签名时的计算量。
- 哈希函数的抗碰撞性确保原始数据无法被篡改(修改内容会导致哈希值变化)。
-
加密哈希值生成签名
- CA使用自己的私钥对哈希值进行加密(如RSA、ECDSA算法),生成签名值(Signature Value)。
- 签名值会被写入证书的
signature
字段,作为证书的一部分。
-
证书最终结构
Certificate:Version: 3Serial Number: 1234...Issuer: CN=DigiCert...Validity: Not Before/After...Subject: CN=example.com...Public Key: RSA 2048...Extensions: (SAN, Key Usage...)Signature Algorithm: sha256WithRSAEncryption # 哈希+加密算法Signature Value: 3a:7b:01... # 加密后的哈希值
2. 验证签名时的反向操作
当浏览器验证证书时:
- 提取证书的原始数据(忽略
signature
字段)。 - 用相同的哈希算法(如SHA-256)重新计算哈希值。
- 用CA的公钥解密签名值,得到CA当初计算的哈希值。
- 比对两个哈希值:
- 如果一致 → 证书未被篡改,且由该CA签发。
- 如果不一致 → 证书无效(可能被伪造或损坏)。
3. 为什么不对原始内容直接签名?
- 性能问题:
非对称加密(如RSA)对大数据量的计算效率极低,而哈希函数速度极快。- 示例:RSA加密1KB数据比加密256位哈希慢数百倍。
- 安全性等价:
哈希函数的抗碰撞性(无法找到相同哈希的不同数据)保证了“对哈希签名”等同于“对原始数据签名”。 - 标准化实践:
PKI体系(如X.509标准)和RFC文档均明确要求先哈希再签名。
4. 关键区别:哈希签名 vs. 原始内容签名
场景 | 对哈希签名 | 对原始内容直接签名 |
---|---|---|
计算效率 | 高效(仅加密短哈希值) | 极低(加密完整证书数据) |
安全性 | 依赖哈希函数的抗碰撞性 | 安全性相同,但无实际优势 |
实际应用 | 所有标准证书(如SSL/TLS) | 几乎不存在(仅理论可能) |
OpenSSL实现 | sha256WithRSAEncryption | 无此类算法 |
5. 技术标准中的定义
- RFC 5280(X.509证书标准):
明确要求签名过程为:
TBS证书数据 → 哈希 → 加密哈希 → 签名值
(TBS = “To Be Signed”,即待签名部分)。 - 签名算法标识:
证书中的Signature Algorithm
字段(如sha256WithRSAEncryption
)直接表明先哈希后加密。
6. 示例:OpenSSL生成签名
# 1. 生成证书请求(CSR)和私钥
openssl req -newkey rsa:2048 -nodes -keyout key.pem -out csr.pem# 2. CA签发证书时,实际是对TBS部分的哈希签名
openssl x509 -req -in csr.pem -CA ca.crt -CAkey ca.key -sha256 -out cert.pem
-sha256
指定哈希算法,CA用私钥(ca.key
)加密哈希值生成签名。
7. 常见误解澄清
- 误解:“签名是对整个证书(包括签名本身)加密。”
正解:签名是对除签名字段外的所有数据(TBS部分)的哈希值加密,否则会导致循环依赖。 - 误解:“不同哈希算法(如SHA-1 vs SHA-256)的签名安全性差异大。”
正解:哈希算法影响安全性,但核心风险在于加密算法(如RSA密钥长度)。SHA-1因碰撞风险被弃用,但签名机制不变。
总结
- CA对证书的哈希值签名,而非原始内容,这是出于效率和标准的考虑。
- 验证时通过比对哈希值来确保证书完整性和来源可信。
- 这一机制是PKI体系的基础,所有主流证书(如SSL/TLS、代码签名)均遵循此规则。