4. 证书颁发机构(CA)与自签名证书:公共CA与私有CA的区别、自签名证书的创建与使用场景

做 TLS 配置,绕不开一个核心角色——证书颁发机构,也就是 CA。说白了,CA 就是互联网上的“身份局”,负责给网站、服务器甚至个人签发数字身份证。这章我带你吃透公共 CA、私有 CA 和自签名证书的区别。这三个东西,我在项目里见得太多了,选错了后面全是坑。

4.1 公共 CA vs 私有 CA:一条明显的分界线

先聊公共 CA。像 Let’s Encrypt、DigiCert、GlobalSign 这些,你肯定听过。它们签发的证书,默认被所有主流操作系统和浏览器信任。为什么?因为它们的根证书早就预装在你的电脑、手机里了。

私有 CA 则不同。你自己搭一套 CA 基础设施,给公司内部用。比如开发环境、Kubernetes 集群内部通讯、微服务之间的 mTLS。外部浏览器不认你的私有 CA,但你可以把私有 CA 的根证书推送到所有内部设备的信任库中。

对比维度 公共 CA 私有 CA
信任基础 根证书预装在操作系统/浏览器 需要手动推送到信任库
适用场景 面向互联网的网站、公开 API 内部系统、开发环境、容器集群
成本 免费或按年付费 基础设施投入,但无证书费
证书有效期 通常 90 天到 1 年(Let’s Encrypt 90 天) 自己定,我一般设 5-10 年
吊销管理 由 CA 提供 CRL/OCSP 自己维护 CRL/OCSP 服务
审核要求 OV/EV 需要企业资质审核 无外部审核,自行决定

我个人习惯:互联网业务一律用公共 CA 签发的证书,尤其是 Let’s Encrypt,自动化程度极高,配合 ACME 协议能做到全自动续期。内部服务则全部走私有 CA,管理灵活,成本几乎为零。

为什么会这样做?你想想看,如果内部 API 也用公共 CA 的证书,一旦泄露或需要吊销,操作流程会非常繁琐。私有 CA 下,我随时可以签发新证书,撤销旧证书,完全自主控制。

4.2 什么时候该用私有 CA?

我在项目中遇到过好几回,团队图省事,直接拿公共 CA 证书跑内部服务。结果证书到期前没人留意,服务间握手全挂了,排查了一下午才发现。嗯,这就是典型的场景错配。

私有 CA 最合适以下场景:

  • 开发与测试环境:每个开发人员一个独立域名?没必要。自己签个通配符证书,省事又安全。
  • 内部微服务通讯:Kubernetes 集群内的 Pod 之间、服务网格(如 Istio)的 mTLS 策略
  • IoT 设备管理:给设备签发唯一身份证书,实现设备认证
  • Wi-Fi 企业级认证:EAP-TLS 模式下,每个终端都需要客户端证书

注意:私有 CA 的根证书一旦泄露,你所有签发的证书都不再安全。必须把根证书的私钥放在离线环境,我从不让它接触任何在线服务器。签发中间 CA 证书,日常用中间 CA 干活,根证书锁保险柜。

4.3 自签名证书:最简单的选择,但也是最危险的

自签名证书,顾名思义,自己给自己签发,没有上级 CA。你生成的证书自己就是信任锚点。很多开发者在本地测试时这么干,我也干过。

自签名证书 vs 私有 CA 签发的证书:根本区别在于,自签名证书没有父 CA 做背书。私有 CA 下,你把根证书加入信任库后,所有被它签发的证书都会自动被信任。自签名则需要把每个证书都单独加入信任库。

我用 OpenSSL 创建自签名证书的步骤,记一下:

# 1. 生成私钥 (RSA 2048 位或以上)
openssl genrsa -out mykey.pem 2048

# 2. 生成证书签名请求 (CSR)
openssl req -new -key mykey.pem -out mycsr.csr -subj "/CN=myserver.local"

# 3. 直接用私钥自签名,生成证书 (有效期 365 天)
openssl x509 -req -days 365 -in mycsr.csr -signkey mykey.pem -out mycert.crt

# 4. 一步到位(跳过 CSR,常用)
openssl req -x509 -newkey rsa:2048 -keyout mykey.pem -out mycert.crt -days 365 -nodes -subj "/CN=myserver.local"

你拿到 mycert.crt 和 mykey.pem,就能给 Nginx 或 Node.js 配置 HTTPS 了。但在浏览器里访问会看到“不安全”提示。为什么?因为浏览器不认识你这个自签名的根证书。

4.4 自签名证书的适用边界

我曾经在一个内部监控系统的部署文档里,直接用自签名证书,结果每个新同事加入都得手动导入一次证书,体验很差。后来我换成了私有 CA,一次性把根证书推给所有机器,幸福感直线飙升。

自签名证书真正合适的地方:

  • 本地开发:你一个人用,导入一次证书就能消除警告
  • 临时环境:比如临时演示、快速实验,用完就扔
  • 容器镜像构建:构建过程中需要 HTTPS 下载依赖,临时签发自签名证书,结束后丢弃
  • 嵌入式设备原型:初期调试阶段,来不及搭私有 CA

不要在生产环境使用自签名证书。一旦证书丢失或需要更换,你得手动更新所有客户端的信任存储,这在生产环境是不可接受的。生产环境请走公共 CA 或自建私有 CA。

4.5 更深一步:从自签名到私有 CA

很多团队从自签名过渡到私有 CA。其实只需多一步:

  1. 生成根 CA 的私钥和自签名根证书(它本身也是自签名,但作为信任锚点)
  2. 用根 CA 签发一个中间 CA 证书
  3. 日常用中间 CA 签发服务器/客户端证书

我个人习惯:根 CA 证书有效期设 20 年,私钥冷存储;中间 CA 设 5 年;服务器证书按实际情况设 1-2 年。这样既安全又灵活。

CA 体系与证书签发流程 根 CA (自签名) 中间 CA 服务器证书 客户端证书 核心区别: 根 CA 自签名,是信任链的锚点。中间 CA 由根 CA 签发, 日常签发服务器和客户端证书。私有 CA 下,仅需信任根证书。

4.6 避坑指南:我曾经犯过的几个错

  • 把自签名证书用在生产环境:运维离职后,新来的同事不知道证书在哪,服务间调用全部报 SSL 错误。一夜之间紧急重建。
  • 私有 CA 根证书的私钥权限没设好:一个开发人员误操作删了根证书文件,所有由它签发的下级证书全部无法验证。还好有备份。
  • CN 和 SAN 没配全:给内部负载均衡器签发证书,只配了 Common Name,没填 Subject Alternative Names。Chrome 直接不认,Firefox 也报错。现在 SAN 是必须的。
  • 证书续期靠手动:十多个内部服务各自独立签发,到期逐个手动续。后来我统一接了 ACME 或脚本批量续,再也没出过问题。

我建议:如果你在搭建新项目,直接上手私有 CA 吧。成本低、控制力强、长期看比自签名证书省心太多。工具用 cfssl 或 OpenSSL,配合 Ansible 或 Terraform 自动化推送信任根,效率很高。

说到底,自签名证书就像一把临时钥匙,能开门但不好用。私有 CA 才是内部基础设施的正解。这一章的内容基本覆盖了你在实战中会碰到的 CA 选型问题,记牢这几个原则,以后遇到证书部署决策,心里就不慌了。