自签名证书:从生成到信任的完整闭环
自签名证书,说白了就是自己给自己当CA。你签发证书,你自己信任它,不需要第三方机构插手。我在最初接触TLS的时候,觉得自签名证书就是个“玩具”,直到有一次给内网服务做加密通信,才发现它其实非常实用——不需要花钱,不用等审核,几秒钟就能搞定。
咱们这一章就把自签名证书的生成、openssl基础操作、以及如何让系统信任它,一个一个拆开讲。嗯,这里面坑不少,我踩过,你大概率也会遇到。
4.1 openssl基础操作:你只需要记住这几个命令
openssl是个瑞士军刀,功能多到让人头大。但自签名证书这条路,你只需要掌握以下三组命令。我刚开始用的时候,每次都记不住参数,后来干脆写了个小脚本,你也可以试试。
生成私钥
私钥是证书的根,一旦泄露,证书就废了。
openssl genrsa -out mykey.pem 2048
上面的命令生成一个2048位的RSA私钥。位数越高越安全,但性能也会下降。我个人习惯用2048位,够用且快。还可以用 aes256 参数加密私钥文件,这样每次使用都要输密码。
生成证书签名请求(CSR)
CSR是你向CA申请证书的“申请书”,自签名的话,这个CSR是自己批的。
openssl req -new -key mykey.pem -out mycsr.csr
执行后会让你填一堆信息:国家、省份、组织、通用名(Common Name,通常是域名或IP)。
localhost,结果同事用IP访问,提示证书无效,排查了半天。
用私钥和CSR生成自签名证书
openssl x509 -req -days 365 -in mycsr.csr -signkey mykey.pem -out mycert.crt
这个命令直接用私钥给CSR签名,不经过任何CA。365是有效期,你可以改成 -days 3650 让其10年有效。自己用的证书,有效期长点无所谓。
4.2 自签名证书的完整生成流程
上面三步是基础,但实际中我更推荐用一步到位的方法,省事:
openssl req -x509 -newkey rsa:2048 -keyout mykey.pem -out mycert.crt -days 365 -nodes
这条命令一次性生成私钥和自签名证书,-nodes 表示不加密私钥文件,避免每次输入密码。适合自动化脚本。
证书生成后,你可以用下面命令查看内容:
openssl x509 -in mycert.crt -text -noout
你会看到证书的版本、序列号、公钥信息、签名算法等。注意看 Issuer 和 Subject 是一样的——这就是自签名的标志。
4.3 信任自签名证书:让系统认这个“野路子”证书
自签名证书生成好了,怎么让浏览器或客户端信任它?说白了,就是把这个证书加到系统的“受信任的根证书颁发机构”里。
Windows系统
- 双击
mycert.crt,点击“安装证书”。 - 选择“本地计算机”存储位置(需要管理员权限)。
- 选择“将所有证书放入下列存储”,浏览选择“受信任的根证书颁发机构”。
- 完成导入。重启浏览器,再次访问就不会报错了。
macOS系统
- 打开“钥匙串访问”应用。
- 将证书文件拖入“系统”钥匙串。
- 双击该证书,展开“信任”,将“使用此证书时”改为“始终信任”。
- 输入密码保存。可能需要重启浏览器。
Linux系统(以Ubuntu为例)
sudo cp mycert.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
CentOS/RHEL则是:
sudo cp mycert.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
自签名 vs CA签名:该用哪个?
| 特性 | 自签名证书 | CA签名证书 |
|---|---|---|
| 信任链 | 无上级CA | 由受信任的CA链式签名 |
| 成本 | 免费 | 免费(Let's Encrypt)或付费 |
| 浏览器默认信任 | 否 | 是(受信任的CA) |
| 生成速度 | 秒级 | 分钟级(需验证域名) |
| 适合场景 | 开发/测试、内网 | 互联网生产环境 |
| 有效期 | 可任意设置(最长10年) | 通常1年(Let's Encrypt 90天) |
看到这个表格,你大概知道自己的场景该选哪个了。我个人的原则是:凡是外部用户能访问的服务,都用CA签发的证书;内部工具、微服务之间通信、虚拟机测试环境,全用自签名。毕竟维护一套自签名CA的成本几乎为零。
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -addext "subjectAltName=DNS:example.com,DNS:www.example.com,IP:192.168.1.1" -nodes
上面这张图概括了自签名证书从生成到被系统信任的全过程。注意那个虚线箭头——自签名之后,如果不主动做信任注入,系统是不认的。很多新手只做了前三步,然后问“为什么浏览器还是报错?”——嗯,就是因为少了一个信任步骤。