1. 为什么需要自签证书?
在互联网通信中,HTTPS协议已经成为标配。但当我们开发内部系统、测试环境或本地服务时,往往不需要购买商业CA颁发的证书。自签证书(Self-Signed Certificate)就是自己充当CA(证书颁发机构)给自己颁发的证书,它同样能实现加密通信,只是不被浏览器和操作系统默认信任。
我最近在部署内部监控系统时,就遇到了需要快速搭建HTTPS服务的场景。商业证书申请流程太慢,Let's Encrypt又需要域名验证,最终选择用OpenSSL自签证书,整个过程只用了不到10分钟。这种方案特别适合以下场景:
- 开发测试环境
- 内网服务通信
- 物联网设备间加密
- 需要快速验证HTTPS功能的场景
注意:自签证书不应用于生产环境对外服务,浏览器会显示安全警告。正式环境请使用受信任CA颁发的证书。
2. OpenSSL基础环境准备
2.1 检查OpenSSL版本
现代Linux系统通常已预装OpenSSL,首先检查版本:
bash复制openssl version
推荐使用1.1.1及以上版本,支持更现代的加密算法。如果版本过低,建议升级:
bash复制# Ubuntu/Debian
sudo apt update && sudo apt upgrade openssl
# CentOS/RHEL
sudo yum update openssl
2.2 创建工作目录
建议创建专用目录存放证书文件:
bash复制mkdir -p ~/ssl_certs && cd ~/ssl_certs
目录结构最终会包含:
- 私钥文件(.key)
- 证书签名请求(.csr)
- 自签名证书(.crt)
- 可能的其他文件(如.pem)
3. 生成自签证书全流程
3.1 生成RSA私钥
首先生成2048位的私钥:
bash复制openssl genrsa -out server.key 2048
参数说明:
genrsa:生成RSA密钥-out:指定输出文件2048:密钥长度(单位:bit)
安全提示:务必妥善保管.key文件,它是证书安全的基础。建议设置400权限:
bash复制chmod 400 server.key
3.2 创建证书签名请求(CSR)
CSR包含证书的主体信息,执行以下命令交互式创建:
bash复制openssl req -new -key server.key -out server.csr
会提示输入以下信息(示例):
code复制Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Beijing
Locality Name (eg, city) []:Haidian
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:IT Dept
Common Name (e.g. server FQDN or YOUR name) []:myserver.local
Email Address []:admin@example.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: # 直接回车留空
An optional company name []: # 直接回车留空
关键字段说明:
Common Name (CN):必须填写服务访问的域名或IP- 其他信息可根据实际情况填写
3.3 生成自签名证书
直接使用私钥自签名生成证书:
bash复制openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
参数解释:
x509:X.509证书格式-req:输入是CSR文件-days 365:证书有效期(天)-signkey:指定签名私钥
3.4 验证证书内容
生成后检查证书信息:
bash复制openssl x509 -in server.crt -text -noout
重点关注:
- 有效期(Validity)
- 主体信息(Subject)
- 公钥算法(Public Key Algorithm)
- 签名算法(Signature Algorithm)
4. 高级配置技巧
4.1 非交互式生成证书
对于自动化部署,可以使用单条命令非交互生成:
bash复制openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes -subj "/C=CN/ST=Beijing/L=Haidian/O=My Company/OU=IT/CN=myserver.local"
参数说明:
-nodes:不加密私钥-subj:直接指定主体信息
4.2 设置SAN(主题备用名称)
现代浏览器要求证书包含SAN扩展,创建san.cnf文件:
ini复制[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = CN
ST = Beijing
L = Haidian
O = My Company
OU = IT
CN = myserver.local
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = myserver.local
DNS.2 = *.myserver.local
IP.1 = 192.168.1.100
然后生成证书:
bash复制openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt -days 365 -nodes -config san.cnf -extensions v3_req
4.3 证书格式转换
不同场景可能需要不同格式:
PEM转DER:
bash复制openssl x509 -in server.crt -outform der -out server.der
PEM转PKCS#12(含私钥):
bash复制openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12
5. 实际应用场景
5.1 Nginx配置示例
将证书部署到Nginx:
nginx复制server {
listen 443 ssl;
server_name myserver.local;
ssl_certificate /path/to/server.crt;
ssl_certificate_key /path/to/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# 其他配置...
}
5.2 客户端导入根证书
让系统/浏览器信任自签证书:
- 将server.crt导入系统信任库
- 或手动在浏览器中添加例外
Windows导入:
code复制certmgr.msc → 受信任的根证书颁发机构 → 导入
5.3 证书链验证
验证证书有效性:
bash复制openssl verify -CAfile server.crt server.crt
6. 常见问题排查
6.1 浏览器安全警告
现象:浏览器显示"您的连接不是私密连接"
解决方案:
- 确认访问的域名与证书CN/SAN匹配
- 手动添加安全例外(仅限测试环境)
- 对于局域网IP,需要在SAN中添加IP地址
6.2 证书过期
现象:服务突然无法访问,日志显示SSL错误
检查有效期:
bash复制openssl x509 -in server.crt -noout -dates
续签方案:
- 重新生成新证书
- 使用相同CSR重新签名(需私钥):
bash复制openssl x509 -req -days 365 -in server.csr -signkey server.key -out server_new.crt
6.3 私钥保护
最佳实践:
- 私钥权限设置为400
- 不在版本控制中包含.key文件
- 考虑使用密码加密私钥(但会增加自动化难度):
bash复制openssl rsa -aes256 -in server.key -out server.encrypted.key
7. 安全增强建议
-
密钥长度:生产环境建议使用4096位RSA或ECC密钥
bash复制
openssl ecparam -genkey -name secp384r1 -out ecc.key -
算法选择:
- 签名算法优先选择sha384/sha512
- 禁用不安全的协议(SSLv3, TLSv1.0/1.1)
-
证书透明度:
- 正式环境建议配置CT日志
- 测试环境可忽略
-
定期轮换:
- 即使长期有效的证书也应定期更换
- 建议设置不超过1年的有效期
我在实际使用中发现,合理规划证书生命周期非常重要。对于开发测试环境,可以设置较长的有效期(如5年);而对于预生产环境,建议模仿生产环境的证书管理策略,培养良好的安全习惯。