3. 数字证书
好,咱们继续往下走。上一章我们把 X.509 证书的结构拆了个七七八八,你大概知道证书里面塞了公钥、签名、颁发者这些玩意儿。但光知道结构还不够——你拿到的证书是给个人网站用的,还是给银行用的?它是一段纯文本,还是一坨二进制?浏览器怎么判断这个证书是可信的?
这一章,我们就来解决这几个问题。说白了,就是搞清楚三件事:证书分几种类型、证书长什么格式、证书是怎么串成一条链的。
3.1 证书的类型:DV、OV、EV
你打开浏览器,看到地址栏左边有个小锁。点开它,里面会显示证书信息。但同样是锁,背后的验证力度可能天差地别。CA 在签发证书之前,会对申请者做不同程度的身份核验。根据核验的严格程度,证书分为三种:DV(Domain Validation,域名验证型)、OV(Organization Validation,组织验证型)、EV(Extended Validation,扩展验证型)。
我刚开始接触 PKI 的时候,觉得只要有个锁就是安全的。后来帮客户排查一个钓鱼网站,发现对方用的就是 DV 证书——只要证明你控制这个域名,CA 就给你发证。嗯,从那以后我再也不敢只看锁不看类型了。
| 特性 | DV | OV | EV |
|---|---|---|---|
| 验证内容 | 仅验证域名控制权 | 验证域名 + 组织身份 | 验证域名 + 组织身份 + 法律文件 |
| 审核时间 | 几分钟 ~ 几小时 | 1 ~ 3 个工作日 | 3 ~ 7 个工作日 |
| 证书中组织信息 | 无(Subject 中无 O 字段) | 有(包含公司名称、地址) | 有(更详细的法律实体信息) |
| 浏览器地址栏 | 小锁 + https | 小锁 + https | 小锁 + 公司名称(绿色) |
| 适用场景 | 个人博客、测试站点、内部系统 | 企业官网、电商平台 | 银行、金融、高安全需求网站 |
| 价格 | 低(甚至免费,如 Let's Encrypt) | 中等 | 高 |
核心区别一句话:DV 证明「你控制这个域名」,OV 证明「你是一个真实存在的组织」,EV 证明「你是一个经过严格法律审核的组织」。
我个人习惯是:个人项目或者内部工具,用 DV 就够了,免费又方便。但如果是面向客户的商业网站,至少上 OV。至于 EV……说实话,现在浏览器厂商(Chrome、Safari)已经不再在地址栏高亮显示公司名称了,EV 的「视觉优势」在减弱。但如果你做的是金融类应用,EV 仍然是合规的硬要求。
3.2 证书的格式:PEM、DER、PFX/P12
证书在磁盘上怎么存?你从 CA 下载下来的文件,可能是 .crt、.cer、.pem、.der、.p12……这些后缀到底有什么区别?
其实,证书的存储格式主要有三种:PEM、DER、PFX/P12。其他后缀大多是这些格式的别名或包装。
3.2.1 PEM 格式
PEM 是最常见的格式。它本质上是 Base64 编码的二进制数据,加上头尾标记。你可以用任何文本编辑器打开它,看到类似这样的内容:
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIUQoFfV6vX7e8G8z5o8z5o8z5o8z5o8z5o8z5o8z5o8z5o
...
-----END CERTIFICATE-----
PEM 格式的特点:
- 纯文本,可读性好
- 可以包含多个证书(比如证书链)
- 也可以包含私钥(-----BEGIN RSA PRIVATE KEY-----)
- 在 Linux/Unix 系统中广泛使用
你想想看,Nginx、Apache、OpenSSL,这些工具默认都吃 PEM 格式。我个人在服务器上部署证书时,99% 的情况都用 PEM。
3.2.2 DER 格式
DER 是 PEM 的二进制版本。它没有头尾标记,直接就是 ASN.1 编码后的原始字节。你用文本编辑器打开它,看到的是一堆乱码。
DER 格式的特点:
- 二进制,体积比 PEM 小约 30%
- Java 平台偏好 DER 格式
- Windows 系统有时也使用 DER(.cer 文件)
转换起来也很简单:
# PEM 转 DER
openssl x509 -in cert.pem -outform der -out cert.der
# DER 转 PEM
openssl x509 -in cert.der -inform der -out cert.pem
3.2.3 PFX / P12 格式
PFX(Personal Information Exchange)也叫 PKCS#12,是一种容器格式。它可以把证书、私钥、甚至中间证书打包成一个文件,并且用密码保护。
我记得有一次帮客户迁移 IIS 服务器,对方发来一个 .pfx 文件,说「这就是证书」。我一开始没反应过来,以为只是证书本身,结果导入的时候发现私钥也在里面——嗯,这才是 PFX 的真正用途:便携式打包。
PFX/P12 格式的特点:
- 二进制格式,包含证书 + 私钥
- 受密码保护
- Windows 平台、IIS、Tomcat 常用
- 导出时注意:密码不要泄露,私钥不要明文传输
提取 PFX 中的证书和私钥:
# 提取证书(PEM 格式)
openssl pkcs12 -in cert.pfx -nokeys -out cert.pem
# 提取私钥(PEM 格式,加密)
openssl pkcs12 -in cert.pfx -nocerts -out key.pem
# 提取私钥(PEM 格式,无加密)
openssl pkcs12 -in cert.pfx -nocerts -nodes -out key.pem
我的建议:跨平台传输时,优先用 PEM。Windows 内部用 PFX。Java 环境用 DER 或 JKS。记住一个原则——私钥永远不要以明文形式出现在 PEM 或 DER 文件中,除非你明确知道自己在做什么。
3.3 证书链的概念
你拿到一张服务器证书,浏览器凭什么相信它?
答案不是「因为证书本身是真的」,而是因为有一个浏览器信任的 CA 在它上面签了名。但 CA 不止一层——根 CA 签中间 CA,中间 CA 签你的服务器证书。这就形成了一条证书链(Certificate Chain)。
我曾经遇到过一个生产事故:部署完 HTTPS 后,安卓手机访问报错,但 PC 浏览器正常。查了半天,发现是只部署了服务器证书,没把中间证书带上。PC 浏览器缓存了中间证书,所以能拼出完整链;安卓手机没有缓存,链断了。从那以后,我每次部署都会检查「证书链是否完整」。
证书链的结构是这样的:
验证过程是这样的:
- 浏览器拿到服务器证书,看它的「颁发者」是谁。
- 浏览器去找中间 CA 证书(通常由服务器在 TLS 握手时一起发过来)。
- 用中间 CA 的公钥验证服务器证书的签名——如果通过,说明服务器证书是中间 CA 签发的。
- 再看中间 CA 的「颁发者」,找到根 CA 证书(浏览器内置信任)。
- 用根 CA 的公钥验证中间 CA 的签名——如果通过,说明中间 CA 是根 CA 签发的。
- 根 CA 自签名,浏览器信任它(因为它在受信任的根证书列表中)。
整个链条就闭合了。任何一个环节的签名验证失败,浏览器都会报「证书不可信」。
常见坑:部署时只上传服务器证书,忘记上传中间证书。浏览器无法拼出完整链,导致验证失败。我曾经在 Nginx 配置里漏了 ssl_trusted_certificate,结果花了两个小时才定位到问题。记住:服务器证书 + 中间证书 = 完整的证书链文件。
关于证书链,还有两个概念你需要知道:
- 证书链文件(Chain File):把中间证书(可能多个)按顺序拼接成一个 PEM 文件。Nginx 的 ssl_trusted_certificate 就指向它。
- 完整链(Full Chain):服务器证书 + 中间证书拼接在一起。有些 CA 直接提供这个文件,省得你自己拼。
好了,这一章的内容就到这里。证书的类型决定了它的信任级别,格式决定了你怎么用它,证书链决定了它为什么可信。这三件事搞清楚了,你就能在实际工作中正确选择、部署和验证证书了。