OpenSSL 工具:私钥、CSR 与自签名证书
说到 HTTPS,绕不开的一个工具就是 OpenSSL。说实话,它是个又爱又恨的家伙。命令行参数多到让人头大,但关键时刻真靠它救命。
我刚开始做 HTTPS 的时候,最怕的就是生成证书这步。不是命令敲错,就是参数漏了。后来摸出规律——你只要理清私钥、CSR、证书这三者的关系,剩下的就是背熟几条命令。
私钥生成——你的身份凭证
私钥是整个 HTTPS 的根基。它丢了,一切白搭。生成私钥有两种主流算法:RSA 和 ECDSA。
RSA 私钥
RSA 兼容性最好,几乎所有客户端都认。我个人习惯用 2048 位,够安全,性能也平衡。
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private.key
如果你想要传统格式(PEM),也可以这么写:
openssl genrsa -out private.key 2048
ECDSA 私钥
想更轻量?用 ECDSA。密钥更短,性能更好。我推荐曲线 prime256v1。
openssl ecparam -genkey -name prime256v1 -out ecdsa.key
CSR——证书签名请求
有了私钥,下一步就是生成 CSR(Certificate Signing Request)。说白了,CSR 就是你把公钥和你的身份信息打包发给 CA 的申请表。
生成 CSR 时,OpenSSL 会问一堆问题:国家、省份、组织名……真正重要的只有一个——Common Name(CN)。
CN 必须是你的域名。如果证书要同时保护多个子域,得用 Subject Alternative Names(SAN)。这点很多人栽过坑,后面我也会说。
openssl req -new -key private.key -out server.csr
上面的命令会交互式提问。想省事?一次性全塞进去:
openssl req -new -key private.key -out server.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=Dev/CN=myserver.com"
CSR 里有哪些字段?
| 字段 | 含义 | 示例 |
|---|---|---|
| C | 国家代码(2位) | CN |
| ST | 省/州 | Beijing |
| L | 城市 | Beijing |
| O | 组织名称 | MyCompany |
| OU | 部门 | Dev |
| CN | 通用名称(域名) | myserver.com |
自签名证书——自己当 CA
测试环境或内部系统,没必要花钱买 CA 证书。自己签一个就行。
自签名证书就是用你自己的私钥给 CSR 盖章。生成的证书浏览器会报“不受信任”,但在内网或微服务之间完全能用。
openssl x509 -req -days 365 -in server.csr \
-signkey private.key -out server.crt
我建议有效期别设太长,默认 365 天就够了。曾经有个同事把有效期设成 10 年,结果三年后密钥泄露……换证书时才发现 ECC 参数不对,折腾了一下午。
一步到位:直接生成自签名证书
如果不想先生成 CSR,OpenSSL 也提供了更快捷的方式:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
-nodes 表示不加密私钥(开发环境常用),生产环境建议去掉这个参数,给私钥加个密码。
避坑指南
- 我曾经在生成 CSR 时忘了写 SAN,结果证书部署后 HTTPS 一直警告“域名不匹配”。排查了两个小时才意识到——CN 只匹配一个域名,多个域名必须加 SAN。
- 私钥不要放到 Git 仓库里。我在 Code Review 中见过不止一次有人把
.key文件提交上去…… - 用
openssl verify检查证书链。自签名证书不需要链,但如果将来换成 CA 签发的,这一步很容易忘。
核心流程一览
几种场景下用哪个?
| 场景 | 推荐做法 | 工具命令风格 |
|---|---|---|
| 本地开发 | 直接一键生成自签名证书 | openssl req -x509 ... |
| 测试环境 | 先生成私钥 + CSR,再自签 | 分步执行 |
| 向 CA 申请正式证书 | 生成私钥 + CSR,提交 CSR | CSR 必须包含 SAN |
| 内部微服务 TLS | 自签名证书并做双向认证 | 额外生成 CA 证书链 |
OK,这几条命令和思路足够你应付 90% 的证书操作了。下次部署 HTTPS 服务时,记得先把私钥收好,再思考要不要自签。嗯,动手试试看,你会发现其实没那么复杂。