OpenSSL 是处理 SSL/TLS 证书最常用的命令行工具,几乎所有需要 HTTPS 的环境都会用到它。无论是生成自签名证书用于内网测试,还是创建证书签名请求提交给 CA 机构,掌握 OpenSSL 的证书操作都是运维和开发人员的必备技能。本文会从基础概念讲起,逐步演示生成证书的完整流程,并针对不同使用场景给出参数选择和避坑建议。

一、生成私钥与证书签名请求(CSR)
生成 SSL 证书的第一步是创建私钥。私钥用于加密和解密,必须妥善保管,任何人拿到私钥都能伪造你的证书。常用的私钥算法有 RSA 和 ECDSA,RSA 兼容性更好,ECDSA 密钥更短、性能更高。下面以 RSA 2048 位为例,生成一个 PKCS#8 格式的私钥:
openssl genpkey -algorithm RSA -out server.key -pkeyopt rsa_keygen_bits:2048
这条命令会生成一个名为 server.key 的私钥文件。如果你希望私钥带密码保护,可以添加 -aes256 参数,但这样每次启动服务时都需要输入密码,自动化部署时会比较麻烦。对于内部测试环境,通常直接生成不带密码的私钥。
拿到私钥后,下一步是生成证书签名请求(CSR)。CSR 包含你的域名、组织信息以及公钥,提交给 CA 机构后由 CA 签发正式证书。命令如下:
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=IT/CN=ipipp.com"
这里的 -subj 参数直接指定了证书主题,避免交互式输入。如果需要为多个域名或 IP 地址生成证书,可以在 CN 字段写主域名,然后通过 -addext 添加 SAN(Subject Alternative Name)扩展。例如:
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=IT/CN=ipipp.com" -addext "subjectAltName=DNS:ipipp.com,DNS:www.ipipp.com,IP:127.0.0.1"
需要注意的是,如果使用 CA 签发证书,SAN 字段通常由 CA 控制,CSR 中的 SAN 可能被忽略。自签名证书则可以自由控制。
二、自签名证书与 CA 签名证书的选择
对于本地开发、测试环境或者内网系统,自签名证书是最快捷的方案。它不需要外部 CA 参与,直接用自己的私钥签发证书。生成自签名证书的命令如下:
openssl req -x509 -new -key server.key -out server.crt -days 365 -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=IT/CN=ipipp.com" -addext "subjectAltName=DNS:ipipp.com,DNS:www.ipipp.com"
这条命令将 -x509 选项与 -new 结合,表示生成自签名证书而不是 CSR。-days 365 指定证书有效期为一年。自签名证书的缺点是浏览器会警告“不安全”,因为浏览器不信任签发者。但在内网环境中,可以手动将自签名 CA 证书导入到客户端信任库中解决。
如果证书需要被公网用户信任,就必须向受信任的 CA 机构申请签名。此时你只需生成 CSR,把 server.csr 文件提交给 CA,CA 会返回签好的证书文件。这个过程中,私钥始终保留在你自己服务器上,绝不能发给 CA。收到 CA 签发的证书后,通常还需要下载中间证书链,将中间证书和服务器证书拼接在一起才能被客户端正确验证。拼接方法如下:
cat server.crt intermediate.crt root.crt > fullchain.crt
注意顺序:服务器证书在最前,然后是中间证书,最后是根证书(根证书一般不需要包含,因为客户端已经内置)。
三、证书格式转换与常见避坑点
不同的服务器软件对证书格式的要求不一样。Apache、Nginx 通常使用 PEM 格式(Base64 编码的文本文件),而 Windows IIS、Tomcat 有时需要 PKCS#12 格式(.pfx 或 .p12 文件)。OpenSSL 可以轻松完成格式转换。例如,将 PEM 格式的证书和私钥打包成 PKCS#12 格式:
openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt -certfile intermediate.crt
执行该命令时会提示设置导出密码,这个密码在导入到 Windows 证书存储时需要用到。如果你的服务器使用 Java 的 keystore,则可以直接使用 PKCS#12 作为 keystore 格式。
另一个常见的坑是私钥权限问题。在 Linux 系统上,私钥文件 server.key 必须只对运行服务的用户可读,一般设置为 600 或 400 权限。比如:
chmod 600 server.key
如果权限过于宽松,Nginx 或 Apache 启动时可能会报错。另外,生成证书时如果指定了 -aes256 加密私钥,记得在服务配置中去掉密码,否则服务无法自动启动。可以用下面的命令去除私钥密码:
openssl rsa -in encrypted.key -out decrypted.key
还有一个容易忽略的点是证书有效期。自签名证书默认可能只有 30 天,某些 CA 签发的证书最长可达 397 天。定期检查证书过期时间可以使用:
openssl x509 -in server.crt -noout -enddate
在自动化部署脚本中,建议加入证书到期提醒或自动续期逻辑,避免服务突然中断。
四、多域名与通配符证书的生成技巧
如果需要一张证书覆盖多个域名,可以使用通配符证书或者多 SAN 证书。通配符证书只匹配同一级子域名,例如 *.ipipp.com 可以匹配 www.ipipp.com 和 mail.ipipp.com,但不能匹配 a.b.ipipp.com。生成通配符自签名证书时,在 CN 字段填入通配符即可:
openssl req -x509 -new -key server.key -out wildcard.crt -days 365 -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/OU=IT/CN=*.ipipp.com"
多 SAN 证书则通过 -addext 参数添加多个域名和 IP。注意部分老版本 OpenSSL 对 SAN 扩展的支持需要额外配置,建议使用 OpenSSL 1.1.1 及以上版本。
在向 CA 申请多域名证书时,CSR 中的 CN 字段通常会被忽略,CA 以 SAN 列表为准,所以需要在申请页面明确列出所有需要覆盖的域名。自签名证书则可以自由控制 CN 和 SAN 的内容,方便测试各种场景。
最后提醒一点,生成证书后一定要验证证书内容是否正确,尤其是 SAN 字段。使用 openssl x509 -in server.crt -text -noout 查看详细信息,确认 Subject Alternative Name 部分包含了所有需要的域名和 IP,避免出现证书不匹配的错误。