1. 证书基础认知:数字证书到底是什么?
说实话,我刚入行那会儿,对数字证书的理解特别肤浅。就觉得它是个「加密的东西」,具体怎么用、为什么重要,完全没概念。直到有一次线上服务突然挂了,排查半天才发现是证书过期了——嗯,从那以后,我再也不敢小看这玩意儿了。
数字证书,说白了就是网络世界里的「身份证」。你想想看,现实里我们靠身份证证明「我是我」,网络里服务器和客户端怎么互相信任?靠的就是数字证书。它由权威机构(CA,Certificate Authority)签发,里面绑定了持有者的身份信息和公钥。
一句话总结:数字证书 = 身份信息 + 公钥 + CA的数字签名。缺一不可。
1.1 证书的三个核心作用
我习惯把证书的作用归纳为三点。每次给团队新人培训,我都用这个框架讲,效果不错。
- 身份认证——确认对方是不是它声称的那个实体。比如你访问银行网站,浏览器会检查服务器的证书,确保你不是连到了一个钓鱼网站。我在项目中遇到过客户自己签了个证书,结果浏览器疯狂弹警告,用户全跑了。这就是身份认证没做好。
- 数据加密——通过非对称加密协商会话密钥,保证传输内容只有通信双方能看懂。HTTPS 就是干这个的。没有证书加密,你在咖啡厅连公共 WiFi 上网,密码分分钟被截获。
- 完整性校验——防止数据在传输过程中被篡改。证书里的数字签名能保证:如果中间有人改了数据,接收方一验就能发现。我曾经见过一个案例,攻击者劫持了 HTTP 页面插广告,就是因为没有完整性校验。
| 作用 | 通俗解释 | 实际场景 |
|---|---|---|
| 身份认证 | 证明「你是你」 | 浏览器验证服务器证书 |
| 数据加密 | 让偷看的人看不懂 | HTTPS 传输银行卡信息 |
| 完整性校验 | 确保没人动过手脚 | 软件包签名验证 |
1.2 证书的生命周期
证书不是永久的。它从生到死有一套完整流程,我管它叫「证书的一生」。你想想看,如果证书永远不过期,一旦私钥泄露,后果不堪设想。所以生命周期管理是运维的重中之重。
我的习惯:每次部署新服务,第一件事就是把证书到期时间记到日历里,提前 30 天设置提醒。别问我为什么——问就是吃过亏。
1.2.1 申请
你需要向 CA 提交证书签名请求(CSR)。CSR 里包含你的公钥和组织信息。生成 CSR 时,私钥必须自己保管好,绝对不能发给任何人。
# 生成私钥和 CSR(以 RSA 为例)
openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr
这里有个坑:-nodes 参数表示私钥不加密。生产环境我建议去掉这个参数,用密码保护私钥。虽然每次重启服务要输密码,但安全多了。
1.2.2 颁发
CA 收到你的 CSR 后,会验证你的身份。验证通过后,CA 用它的私钥给你的公钥和信息签名,生成正式的证书文件。这个证书文件就是你的「网络身份证」了。
CA 分几种:
- 公共 CA(如 Let's Encrypt、DigiCert)——浏览器默认信任,适合对外服务
- 私有 CA——自己搭建,适合内部系统。我之前的公司就用 OpenSSL 搭了内部 CA,省了不少钱
1.2.3 使用
证书部署到服务器上,配合私钥一起工作。客户端连接时,服务器把证书发给客户端,客户端验证证书的合法性,然后开始加密通信。
验证过程大致是:
- 检查证书是否在有效期内
- 检查证书是否被吊销
- 用 CA 的公钥验证证书签名
- 检查证书域名是否匹配
注意:很多人只检查第 1 步和第 4 步,忽略了吊销检查。我曾经遇到过一个场景:证书被提前吊销了,但服务端没做 OCSP 装订,客户端也没主动查吊销列表,结果那个证书还在被使用——这就是安全隐患。
1.2.4 续期
证书快过期了怎么办?续期。现在 Let's Encrypt 的证书只有 90 天有效期,逼着你自动化续期。我个人强烈建议用 acme.sh 或 certbot 这类工具做自动续期,别手动操作。
# 使用 acme.sh 自动续期
acme.sh --renew -d example.com --force
续期本质上就是重新走一遍申请流程,但 CA 会保留你的身份信息,所以比首次申请快很多。
1.2.5 吊销
私钥泄露、域名变更、员工离职……这些情况都需要吊销证书。吊销后,证书会被加入 CRL(证书吊销列表)或通过 OCSP 实时查询。
吊销的方式有两种:
- CRL——CA 定期发布一个黑名单,客户端下载后比对。缺点是实时性差
- OCSP——客户端实时向 CA 查询某个证书是否有效。实时性好,但 CA 服务器压力大
我建议用 OCSP 装订(OCSP Stapling),让服务器自己定期去 CA 查询结果,然后缓存下来发给客户端。这样既保证了实时性,又减轻了 CA 的压力。
1.3 证书的常见格式
工作中你会遇到各种证书文件格式。我整理了一张表,方便你对照:
| 格式 | 扩展名 | 说明 | 常见用途 |
|---|---|---|---|
| PEM | .pem, .crt, .cer | Base64 编码,文本格式 | Linux 服务器、Nginx |
| DER | .der | 二进制格式 | Java 环境、Windows |
| PKCS#12 | .p12, .pfx | 包含证书和私钥,有密码保护 | Windows IIS、导入导出 |
| JKS | .jks | Java 专用密钥库格式 | Tomcat、Spring Boot |
我的建议:优先用 PEM 格式。它是纯文本,方便查看和调试。用 openssl x509 -in cert.pem -text -noout 就能看到证书的全部信息。
1.4 避坑指南
这些年我踩过的坑不少,挑几个典型的说说:
- 私钥权限——私钥文件一定要设置成 600 或 400,别让其他人能读。我曾经见过有人把私钥放在 Git 仓库里……嗯,那场面,不说了。
- 证书链不完整——只部署服务器证书,没部署中间 CA 证书。某些客户端(比如老旧手机)会验证失败。解决办法是把服务器证书和中间 CA 证书合并成一个文件。
- 通配符证书的局限——
*.example.com只能匹配a.example.com,不能匹配a.b.example.com。别问我怎么知道的。 - 忽略证书透明度(CT)——现在主流浏览器要求证书必须包含 SCT(签名证书时间戳)。用 Let's Encrypt 会自动处理,但自签名证书不行。