第二章 证书基础:X.509、密钥对与信任链
在搭建 mTLS 环境之前,你得先搞懂证书到底是个什么东西。说白了,证书就是网络世界里的身份证加公章。我刚开始搞这块的时候,光看着那些 .pem 文件里的乱码就头疼——后来才明白,理解证书就是理解三个核心:X.509 结构、非对称密钥、以及信任怎么传递。
2.1 公钥 / 私钥对:锁和钥匙的关系
公钥和私钥,你可以想象成一把锁和一把钥匙。公钥是锁,随便分给别人;私钥是钥匙,只有你自己拿着。别人用你的公钥加密数据,只有你的私钥能解开。反过来,你用私钥签名,别人用公钥验证签名是否是你本人做的。
我在项目里遇到过最坑的事——有人把私钥明文提交到了 Git 仓库,然后就等着被通报吧。所以记住:私钥绝不离开本机,更别传给别人。
| 概念 | 比喻 | 用途示例 |
|---|---|---|
| 公钥 | 锁(可公开) | 加密数据、验证签名 |
| 私钥 | 钥匙(保密) | 解密数据、生成签名 |
2.2 X.509 证书结构:一张表拆解给你看
X.509 是国际标准,定义了证书长什么样。每个证书其实就是一个数据块,按 ASN.1 语法序列化。我习惯把它当成一个“简历”,上面有基本信息、持有者、颁发者、以及一个最重要的东西——签名。
关键字段如下:
| 字段 | 含义 | 我常用的检查方法 |
|---|---|---|
Subject | 证书持有者身份 | 用 openssl x509 -in cert.pem -text 看 |
Issuer | 签发者身份(CA) | 与 Subject 一致就是自签名 |
Validity | 起止时间 | 过期证书会导致握手失败,我踩过这坑 |
Public Key | 持有者的公钥 | 看算法和长度是否合规 |
Signature | CA 对证书的签名 | 这是防篡改的关键 |
openssl x509 -in cert.pem -noout -subject -issuer -dates 一行就能看到核心信息,不用看大段输出。
2.3 CA 与自签名根证书
CA(Certificate Authority) 是受信任的第三方,负责签发证书。浏览器里预装了一大堆 CA 根证书,所以你可以信任 *.google.com 的证书。但在内网或测试环境,你没必要去找公共 CA,自己造一个自签名根证书就行。
自签名根证书,说白了就是自己当 CA。谁都不信,就信自己。我个人习惯在每套测试环境里单独生成一个根证书,然后用它给服务端和客户端签发证书。这样管理起来清晰,而且删掉根就相当于作废整个链条。
我曾经遇到一个团队,给一百台机器每台都单独自签名,结果互相不认。后来全部推倒重来,统一用一个自签名根证书签发——世界清净了。
- 公共 CA 证书:浏览器/系统信任,适合生产。
- 自签名根证书:自己生成并手动导入信任库,适合测试和内部系统。
2.4 证书链:信任的传递
证书链就是信任的等级传递。比如:根证书 → 中间 CA → 服务器证书。根证书自己签自己,中间 CA 用根证书签,服务器证书用中间 CA 签。客户端验证时,从服务器证书开始往上找,直到找到自己信任的根证书。
为什么要有中间 CA?根证书一旦泄露就全完了。所以根证书通常离线存储,日常签发用中间 CA。我在一次安全审计中看到有人把根私钥放在线上服务器里——冷汗都下来了。
下面这张图把证书链的流转关系画清楚了:
2.5 证书验证流程(核心逻辑)
mTLS 双向验证时,客户端和服务端各自出示证书,然后互相验证对方的信任链。我记得第一次配置双向认证时,两边证书链都对,就是没把根证书导入 truststore——结果握手失败。排查半天才发现是信任缺失。
验证的关键步骤:
- 检查证书有效期(Validity)——过期直接拒。
- 用颁发者的公钥验证签名——确保证书没被篡改。
- 向上查找证书链,直到找到信任的根证书。
- 检查 CRL(证书吊销列表) 或 OCSP——确保证书没被吊销。
2.6 快速生成自签名根证书和证书链
下面是我自己经常用的一套命令,生成一个根证书,然后签发一个服务端证书。你可以直接复制去测试:
# 1. 生成根私钥(2048位 RSA)
openssl genrsa -out root.key 2048
# 2. 生成自签名根证书
openssl req -x509 -new -nodes -key root.key -sha256 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyTestCA/CN=MyRootCA" \
-out root.crt
# 3. 生成服务器私钥
openssl genrsa -out server.key 2048
# 4. 生成服务器证书请求(CSR)
openssl req -new -key server.key \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyTest/CN=myserver.local" \
-out server.csr
# 5. 用根证书签发服务器证书(有效期1年)
openssl x509 -req -in server.csr -CA root.crt -CAkey root.key \
-CAcreateserial -out server.crt -days 365 -sha256
# 6. 查看签发后的证书链
openssl verify -CAfile root.crt server.crt
这段命令背后其实就是在做今天讲的三件事:生成密钥对、创建自签名根、用根签子证书。记住一个原则:根证书一定要保存好私钥,放在离线安全的地方。子证书丢了可以重新签发,根丢了整个信任体系就垮了。
以上就是证书基础的全部核心内容。弄懂了 X.509 结构、密钥对关系、CA 和证书链,你就已经打下了 mTLS 搭建的半壁江山。接下来用这些知识去配置实际环境,会顺畅很多。