CA 签名后的证书是否包含公钥
是的,CA 签名后的证书一定包含公钥。
X.509 证书中有一个字段:
Subject Public Key Info(SPKI)
这个字段就是从你提交的 CSR 中拿过来的公钥,写进证书内部。这也是证书最关键的内容之一。
证书里的公钥来自哪里
非常明确:
- 来自 CSR 中的公钥
- CSR 中的公钥来自你本地生成的密钥对
流程:
[你本地生成密钥] → 公钥 + 私钥
↓
公钥被写入 CSR
↓
CA 从 CSR 中读公钥 → 写进 X.509 证书
拿到证书后还需要单独保存公钥吗
通常不需要。原因:
- 证书本身已经包含公钥
- 证书是「公钥 + 身份 + CA 签名」的组合体
所以只要你保存这个证书本身,就等同于保存了公钥。
你只需要额外保存的是 私钥——证书里绝对不会包含你的私钥。
是否可以只拿证书就进行加密/验证签名
可以。因为证书中已经有:
- 持有者的公钥
- 经过 CA 的签名
- 使用者信息(Subject)
- 有效期
- 证书用途(EKU)
所以别人收到你的证书后,可以:
- 用你的公钥验证你发出的签名——例如 TLS、JWT、S/MIME、代码签名
- 用证书携带的公钥对你加密——例如 TLS 握手中的密钥交换
CA 收到 CSR 后做了什么
CSR 中包含:
- 你的公钥
- 你的主体信息(CN、组织名、域名等)
- 你的 CSR 签名(用你的私钥签的)
CA 收到 CSR 后会做四件事:
- 验证 CSR 的签名:用 CSR 中的公钥验证,证明这个 CSR 是你生成的(证明你拥有私钥)。
- 验证身份信息:根据 CA 的级别验证域名归属、公司真实性等。
- 把 CSR 中的公钥写进证书的 X.509 字段:证书中的公钥就是 CSR 里的那个公钥,不会改。
- 用 CA 的私钥对证书内容进行数字签名:签名对象是证书内容(含你的公钥 + 身份 + 用途 + 有效期)。最终生成 X.509 证书。
信任链:为什么别人用 CA 公钥验证
别人验证你的证书时,用的是 CA 的公钥,不是你的公钥。
为什么?因为他们要验证:
「这个证书到底是不是 CA 签过的?」
验证流程:
- 别人收到你的证书
- 从证书里取出 CA 的名字(Issuer)
- 在本地操作系统/浏览器中找到对应 CA 的根证书
- 使用 CA 的公钥去验证你证书上的签名
如果验证通过:
- 证书确实由该 CA 签发
- 证书内部的公钥是可信的
两套密钥体系,不能混
你的常见疑问:「证书里放的是我的公钥,那别人应该用我的公钥验证?这不是验证不通过吗?」
说得对——别人确实不能用你的公钥来验证证书,验证必然失败。因为你的公钥不是用于验证证书签名的。
- 证书签名是谁生成的? CA 的私钥
- 验证证书应该用谁的公钥? CA 的公钥
你的公钥在证书里起的作用是:
- 别人在信任你的证书后,用你的公钥来验证你签名的内容
- 或者用你的公钥对你加密(例如 TLS)
完整信任链:
[CA 私钥] --签名--> [你的证书(含公钥)]
│
▼
别人用 [CA 公钥] 验证证书
│
▼
相信证书里的 [你的公钥]
│
▼
用你的公钥对你加密 / 验证你签名的数据
X.509 证书结构
X.509 是一种标准格式。所有常见的数字证书(HTTPS/TLS 证书、客户端证书、代码签名证书等)都是 X.509 格式。
X.509 证书由几个主要部分组成:
- Subject(证书所有者)
- Subject Public Key Info(你的公钥)
- Issuer(签发 CA)
- Validity(有效期)
- Key Usage / Extended Key Usage(用途)
- SAN(域名)
- CA 的数字签名(核心)
X.509 证书结构示意
{
证书内容(你的信息、公钥、用途...),
由 CA 用自己的私钥生成的签名
}
别人收到证书后,通过 CA 的公钥就能验证:
- 证书内容未被修改
- 证书确实由该 CA 签发
- 公钥的确属于证书中声明的主体
本篇准则
- 证书含公钥——拿到证书后无需单独保存公钥。
- 别人用 CA 公钥验证书——你的公钥用于通信,不用于证书验证。
- 两套密钥体系——CA 私钥/公钥用于证书信任;你的私钥/公钥用于通信。
- X.509 是行业标准——HTTPS、代码签名、S/MIME 都是这个格式。