在搭建本地开发环境或内部测试系统时,我们经常需要HTTPS加密连接。但购买商业SSL证书不仅需要费用,还需要域名验证等流程。自签证书(Self-Signed Certificate)就是在这种情况下最实用的解决方案。
自签证书的特点:
注意:自签证书不应用于生产环境,用户访问时会看到安全警告。正式网站请使用Let's Encrypt等免费CA或购买商业证书。
OpenSSL是生成证书的核心工具,首先检查是否已安装:
bash复制openssl version
如果未安装,各系统安装方法如下:
Ubuntu/Debian:
bash复制sudo apt update && sudo apt install openssl
CentOS/RHEL:
bash复制sudo yum install openssl
macOS:
通常已预装,如版本过旧可通过Homebrew更新:
bash复制brew install openssl
建议建立专门目录存放证书文件:
bash复制mkdir -p ~/ssl_certs && cd ~/ssl_certs
私钥是证书安全的基础,生成2048位的RSA私钥:
bash复制openssl genrsa -out server.key 2048
参数解析:
genrsa: 生成RSA密钥-out server.key: 输出到server.key文件2048: 密钥长度,推荐2048位(安全性足够且性能较好)安全提示:可将私钥权限设置为仅所有者可读:
bash复制chmod 400 server.key
如果需要单独获取公钥用于其他用途:
bash复制openssl rsa -in server.key -pubout
输出示例:
code复制-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwZ1J6LvJ7zJwYwJ9Xz5X
...
-----END PUBLIC KEY-----
生成有效期为10年的自签名证书:
bash复制openssl req -new -x509 -key server.key -out server.crt -days 3650
执行后会交互式询问证书信息:
专业建议:对于开发环境,Common Name可设为:
localhost(浏览器访问时使用https://localhost)- 服务器内网IP (如
192.168.1.100)- 通配符
*.yourdomain.com(适用于多子域名)
bash复制openssl x509 -text -in server.crt
输出包含:
bash复制openssl x509 -in server.crt -noout -dates
示例输出:
code复制notBefore=Jun 1 12:00:00 2023 GMT
notAfter=May 29 12:00:00 2033 GMT
nginx复制server {
listen 443 ssl;
server_name localhost;
ssl_certificate /path/to/server.crt;
ssl_certificate_key /path/to/server.key;
# 其他配置...
}
apache复制<VirtualHost *:443>
ServerName localhost
SSLEngine on
SSLCertificateFile "/path/to/server.crt"
SSLCertificateKeyFile "/path/to/server.key"
# 其他配置...
</VirtualHost>
让浏览器信任自签证书(以Chrome为例):
将server.crt导入系统证书库
/usr/local/share/ca-certificates/后执行update-ca-certificates重启浏览器
现象:浏览器显示"您的连接不是私密连接"
解决:
现象:SSL_ERROR_EXPIRED_CERTIFICATE
解决:重新生成证书并延长有效期
现象:SSL_ERROR_BAD_CERT_DOMAIN
解决:确保证书和私钥是配对生成的,没有混淆文件
推荐使用ECDSA算法替代RSA:
bash复制# 生成ECDSA私钥
openssl ecparam -genkey -name prime256v1 -out ecdsa.key
# 生成证书
openssl req -new -x509 -key ecdsa.key -out ecdsa.crt -days 3650
现代浏览器要求证书包含SAN扩展,创建san.cnf文件:
code复制[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
[req_distinguished_name]
countryName = CN
stateOrProvinceName = Beijing
localityName = Beijing
organizationName = My Company
commonName = localhost
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = 127.0.0.1
IP.1 = 192.168.1.100
然后生成证书:
bash复制openssl req -new -x509 -key server.key -out server.crt -days 3650 -extensions v3_req -config san.cnf
生成CA私钥和根证书:
bash复制openssl genrsa -out ca.key 2048
openssl req -new -x509 -key ca.key -out ca.crt -days 3650
用CA签署服务器证书:
bash复制openssl req -new -key server.key -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650
这样所有由该CA签发的证书只需信任一次CA根证书即可。
创建generate_ssl.sh自动化脚本:
bash复制#!/bin/bash
# 配置参数
DAYS=3650
KEY_SIZE=2048
COUNTRY="CN"
STATE="Beijing"
CITY="Beijing"
ORG="My Company"
COMMON_NAME="localhost"
# 生成私钥
openssl genrsa -out server.key $KEY_SIZE
# 生成证书请求
openssl req -new -key server.key -out server.csr \
-subj "/C=$COUNTRY/ST=$STATE/L=$CITY/O=$ORG/CN=$COMMON_NAME"
# 生成自签名证书
openssl x509 -req -days $DAYS -in server.csr -signkey server.key -out server.crt
# 清理临时文件
rm server.csr
echo "SSL证书生成完成:"
echo "- 私钥: server.key"
echo "- 证书: server.crt"
使用权限:
bash复制chmod +x generate_ssl.sh
./generate_ssl.sh
虽然自签证书有效期较长,但也需要定期维护:
监控到期时间:
bash复制openssl x509 -in server.crt -noout -enddate
续期流程:
最佳实践:
私钥保护:
证书分发:
加密强度:
在实际开发中,我通常会在项目文档中专门记录证书生成过程和更新日志,特别是当团队多人协作时。对于需要频繁重建的开发环境,将证书生成步骤写入Dockerfile或部署脚本是提高效率的好方法。