3. 核心模块拆分:证书申请、签发、吊销、存储与查询
说实话,很多团队做 PKI 系统,上来就撸代码。结果呢?三个月后发现代码拧成一团麻花。证书申请和签发混在一起,吊销逻辑塞在存储层,查询接口慢得像蜗牛。
我个人习惯,动手前先把模块边界画清楚。今天我们就聊聊这五个核心模块——申请、签发、吊销、存储、查询。每个模块该干什么、不该干什么,边界在哪,我会结合踩过的坑来讲。
3.1 证书申请模块:入口的守门人
证书申请模块,说白了就是用户和系统之间的第一道门。用户提交 CSR(证书签名请求),系统做校验,然后决定要不要往下走。
这个模块的核心职责有三块:
- 身份验证:确认申请者确实是他声称的那个人。我见过一个项目,这里没做严格校验,结果有人冒用他人邮箱申请了证书,差点出安全事故。
- CSR 校验:检查 CSR 格式、公钥算法、域名合法性。嗯,这里要注意,有些 CSR 里会带奇怪的扩展字段,必须过滤掉。
- 策略匹配:判断申请是否符合证书策略(比如有效期不能超过 90 天、必须包含 SAN 等)。
我曾经遇到一个案例:申请模块里混了签发逻辑,结果每次申请都要等签发完成才返回。高峰期时,申请队列堵死,用户超时重试,系统雪崩。后来我们把申请和签发拆成异步流程,问题才解决。
3.2 证书签发模块:核心中的核心
签发模块是 PKI 的心脏。它接收经过校验的申请,生成证书,然后用 CA 私钥签名。
这里有几个关键点:
- 私钥保护:CA 私钥绝对不能出 HSM(硬件安全模块)或 KMS(密钥管理服务)。我见过有人把私钥文件放在磁盘上,还忘了加密——这等于把大门钥匙挂在门上。
- 序列号管理:每个证书必须有唯一序列号。分布式环境下,序列号生成不能依赖数据库自增,否则会冲突。我建议用雪花算法或 Redis 原子递增。
- 签名性能:RSA 2048 签名大约每秒几百次,ECDSA 可以到几千次。如果量很大,考虑用多台签名服务器 + 负载均衡。
| 算法 | 签名速度(次/秒) | 推荐场景 |
|---|---|---|
| RSA 2048 | ~300 | 兼容性要求高 |
| ECDSA P-256 | ~2000 | 性能优先 |
| Ed25519 | ~5000 | 现代系统 |
3.3 证书吊销模块:紧急刹车
证书吊销,说白了就是给证书判死刑。私钥泄露、域名变更、员工离职——这些场景都需要吊销证书。
吊销模块要处理两件事:
- CRL(证书吊销列表):定期发布的吊销清单。CRL 不能太大,否则下载慢。我建议 CRL 超过 10MB 就分片。
- OCSP(在线证书状态协议):实时查询证书状态。OCSP 响应必须快,一般要求在 100ms 以内。
你想想看,如果吊销模块挂了,已经泄露的证书还在有效期内,攻击者就能继续用。所以吊销模块必须高可用,我一般会部署至少两个实例,一个主一个备。
3.4 证书存储模块:数据的保险箱
存储模块负责把证书、私钥、CSR、吊销记录等数据持久化。这里的选择很多,但核心原则只有一个:安全第一,性能第二。
我常用的分层存储策略:
- 热数据:最近 30 天签发的证书,放在 Redis 或内存缓存里,查询快。
- 温数据:30 天到 1 年的证书,放在 MySQL 或 PostgreSQL 里,做好索引。
- 冷数据:超过 1 年的证书,归档到对象存储(如 S3、MinIO),只保留元数据在数据库里。
嗯,这里要注意:私钥绝对不能明文存。必须用 KMS 加密后再存,而且加密密钥和存储位置要分开。我曾经见过一个团队,私钥和加密密钥放在同一个数据库里——那加密还有什么意义?
3.5 证书查询模块:用户的望远镜
查询模块看起来简单,其实最容易出问题。用户要查证书、查吊销状态、查历史记录——如果查询慢,整个系统的体验就毁了。
查询模块的设计要点:
- 索引优化:按序列号、域名、申请人、有效期等字段建索引。我建议用覆盖索引,避免回表查询。
- 缓存策略:热点证书(比如最近签发的)缓存到 Redis,设置合理的 TTL。注意缓存和数据库的一致性,我一般用 Cache-Aside 模式。
- 分页与限流:查询接口必须做分页,防止一次查几十万条数据把数据库打崩。同时要做限流,防止恶意爬虫。
3.6 模块关系图
下面这张图展示了五个模块之间的协作关系。你仔细看,申请和签发是异步的,存储是中心化的,查询和吊销都依赖存储层。
3.7 模块拆分的原则
最后,我总结几条模块拆分的经验:
- 单一职责:每个模块只做一件事。申请模块不签发,签发模块不存储,存储模块不查询。
- 异步解耦:模块之间通过消息队列通信,不要直接调用。这样即使某个模块挂了,其他模块还能继续工作。
- 独立部署:每个模块可以独立部署、独立扩缩容。申请模块压力大,就多部署几个实例;查询模块压力小,就少部署几个。
- 统一监控:每个模块都要暴露健康检查和指标(如 QPS、延迟、错误率)。我习惯用 Prometheus + Grafana 做统一监控。