自签名证书:从生成到信任的完整闭环

自签名证书,说白了就是自己给自己当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)。

提示:Common Name一定要写对。浏览器访问时,如果域名不匹配,会弹出安全警告。我曾在测试环境写了个 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 是一样的——这就是自签名的标志。

注意:自签名证书没有上级CA背书。浏览器、操作系统默认都不信任它。你在开发环境或内网用它没问题,但上了生产环境,用户会看到“您的连接不是私密连接”这样的红屏警告。我曾经为了省事,直接在生产环境用自签名证书,结果被客户投诉……从那以后,生产环境一律用Let's Encrypt或商业CA。

4.3 信任自签名证书:让系统认这个“野路子”证书

自签名证书生成好了,怎么让浏览器或客户端信任它?说白了,就是把这个证书加到系统的“受信任的根证书颁发机构”里。

Windows系统

  1. 双击 mycert.crt,点击“安装证书”。
  2. 选择“本地计算机”存储位置(需要管理员权限)。
  3. 选择“将所有证书放入下列存储”,浏览选择“受信任的根证书颁发机构”。
  4. 完成导入。重启浏览器,再次访问就不会报错了。

macOS系统

  1. 打开“钥匙串访问”应用。
  2. 将证书文件拖入“系统”钥匙串。
  3. 双击该证书,展开“信任”,将“使用此证书时”改为“始终信任”。
  4. 输入密码保存。可能需要重启浏览器。

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
核心区别:Windows和macOS是通过图形界面导入证书,Linux则是命令行操作。不过底层逻辑一样——把证书加到系统CA bundle中。我建议在开发机上统一用一个内部CA证书,所有自签名证书由这个CA签发,这样只需要信任一个根证书,管理起来方便很多。

自签名 vs CA签名:该用哪个?

特性自签名证书CA签名证书
信任链无上级CA由受信任的CA链式签名
成本免费免费(Let's Encrypt)或付费
浏览器默认信任否是(受信任的CA)
生成速度秒级分钟级(需验证域名)
适合场景开发/测试、内网互联网生产环境
有效期可任意设置(最长10年)通常1年(Let's Encrypt 90天)

看到这个表格,你大概知道自己的场景该选哪个了。我个人的原则是:凡是外部用户能访问的服务,都用CA签发的证书;内部工具、微服务之间通信、虚拟机测试环境,全用自签名。毕竟维护一套自签名CA的成本几乎为零。

避坑:我遇到过同事把自签名证书的有效期设成20年,结果某天系统更新后,openssl不再支持过长的有效期(新版本限制最多825天),证书直接失效。所以建议自签名证书有效期不要超过10年,并且提前做好续期提醒。
小技巧:用openssl一次性生成带Subject Alternative Names(SAN)的自签名证书,这样可以让证书同时支持多个域名和IP。命令示例:
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
自签名证书生成与信任流程 1. 生成私钥 genrsa -out mykey.pem 2048 2. 生成CSR req -new -key mykey.pem 3. 自签名 x509 -req -signkey 证书 mycert.crt 信任操作(导入CA) Windows macOS Linux 说明 自签名证书需要手动导入 系统受信任根存储。 否则浏览器报“不安全”。

上面这张图概括了自签名证书从生成到被系统信任的全过程。注意那个虚线箭头——自签名之后,如果不主动做信任注入,系统是不认的。很多新手只做了前三步,然后问“为什么浏览器还是报错?”——嗯,就是因为少了一个信任步骤。