【openssl生成自签证书】
制作公司内部使用的自签HTTPS证书可以通过OpenSSL工具完成,以下是详细步骤:
步骤1:安装OpenSSL
- Windows:从OpenSSL官网下载安装包
- Linux:通常已预装,可通过
openssl version
验证,否则使用包管理器安装(如apt install openssl
) - macOS:可通过Homebrew安装
brew install openssl
步骤2:生成私钥
首先生成一个RSA私钥(2048位或更高):
# 生成2048位私钥,使用AES256加密
openssl genrsa -aes256 -out company.key 2048
执行后会提示设置密码,记住这个密码后续会用到。
步骤3:生成证书签名请求(CSR)
openssl req -new -key company.key -out company.csr
执行后需要填写证书信息:
- Country Name (2 letter code):国家代码,如CN
- State or Province Name:省份
- Locality Name:城市
- Organization Name:公司名称
- Organizational Unit Name:部门名称
- Common Name:非常重要,填写服务器域名或IP(如
internal.company.com
) - Email Address:邮箱地址
- 其他可选字段直接按回车跳过
步骤4:生成自签证书
使用私钥和CSR生成自签证书,有效期设置为3650天(约10年):
openssl x509 -req -days 3650 -in company.csr -signkey company.key -out company.crt
步骤5:转换证书格式(如需)
如果需要PFX格式(Windows服务器常用):
openssl pkcs12 -export -out company.pfx -inkey company.key -in company.crt
最终文件说明
company.key
:私钥文件,需妥善保管company.csr
:证书签名请求,自签时可忽略company.crt
:自签证书文件,用于服务器配置company.pfx
:PFX格式证书(如需)
注意事项
- 自签证书不受浏览器信任,内部使用时需手动将证书导入信任列表
- 生产环境建议使用正规CA颁发的证书
- 私钥文件必须严格保密,仅限服务器管理员访问
- 定期更新证书,避免过期
配置服务器时,需将私钥和证书文件部署到Web服务器(如Nginx、Apache、IIS等)的相应配置目录中。
要让浏览器在地址栏不显示“不安全”警告,使用自签HTTPS证书时,需满足以下条件之一:
1. 使用受信任的CA签发的证书
自签证书(Self-Signed)默认不被浏览器信任。解决方法:
- 免费证书:申请受信任的CA(如 Let’s Encrypt、ZeroSSL)签发的证书,支持自动续期。
# 使用 certbot (Let's Encrypt) sudo apt install certbot sudo certbot certonly --nginx -d yourdomain.com
- 企业级证书:购买商业证书(如 DigiCert、Sectigo)。
2. 将自签证书手动添加到系统/浏览器信任库
适用场景:仅限本地开发或内网环境。
步骤:
-
生成自签证书(如用 OpenSSL):
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \-keyout server.key -out server.crt -subj "/CN=yourdomain.com" \-addext "subjectAltName=DNS:yourdomain.com,DNS:*.yourdomain.com"
- 注意添加
subjectAltName
(现代浏览器要求)。
- 注意添加
-
将证书导入系统信任库:
- Windows:
- 双击
.crt
文件 → “安装证书” → 选择“本地计算机” → 存入“受信任的根证书颁发机构”。
- 双击
- macOS:
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain server.crt
- Linux(以 Ubuntu 为例):
sudo cp server.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates
- Windows:
-
浏览器信任:
- Chrome/Firefox 默认使用系统证书库,Edge/Safari 同理。
- Firefox 需单独导入:选项 → 隐私与安全 → 证书 → “查看证书” → 导入
.crt
。
3. 本地开发时的特殊处理
方法一:使用 localhost
- 浏览器对
http://localhost
和https://localhost
的限制较宽松(自签证书可能不显示警告)。 - 确保证书的
Common Name (CN)
或SAN
包含localhost
。
方法二:使用 .dev
或 .test
等保留域名
- 修改本地 hosts 文件指向
127.0.0.1
(如mysite.test
),并确保证书匹配该域名。
方法三:浏览器启动参数(临时测试)
- Chrome(不推荐生产环境):
google-chrome --ignore-certificate-errors # 忽略所有证书错误 google-chrome --ignore-certificate-errors-spki-list=[证书指纹] # 忽略特定证书
4. 其他注意事项
- 证书有效期:过期的证书会触发警告。
- HSTS 预加载:若域名在浏览器的 HSTS 列表中,强制要求有效证书。需清除 HSTS 状态(Chrome 访问
chrome://net-internals/#hsts
)。 - 代码中忽略证书错误(仅开发):
- Node.js:
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // 禁用证书验证
- Python Requests:
requests.get('https://yourdomain.com', verify=False)
- Node.js:
总结建议
- 生产环境:必须使用受信任的 CA 证书(如 Let’s Encrypt)。
- 本地开发:手动信任自签证书,或使用
localhost
规避限制。 - 浏览器警告无法完全去除:自签证书在未手动信任的设备上始终会显示“不安全”。
通过以上方法,可确保浏览器地址栏不再显示“不安全”提示。
subjectAltName
(主题备用名称,简称 SAN)是 X.509 证书的一个扩展字段,用于指定证书可以保护哪些域名或IP地址。它的作用是解决传统证书中 Common Name (CN)
字段的局限性,确保现代浏览器和应用程序能正确验证证书的适用范围。
为什么需要 subjectAltName
?
-
取代
Common Name (CN)
的不足:- 早期证书仅依赖
CN
字段(如CN=example.com
)验证域名。 - 现代浏览器(如 Chrome、Firefox)已完全忽略
CN
,仅根据subjectAltName
验证域名(遵循 RFC 6125)。
- 早期证书仅依赖
-
支持多域名和通配符:
- 一个证书可以通过
SAN
保护多个域名(如example.com
、api.example.com
、blog.example.com
)。 - 通配符需明确写在
SAN
中(如*.example.com
)。
- 一个证书可以通过
-
兼容性:
- 若证书缺少
SAN
,浏览器会直接报错(如ERR_CERT_COMMON_NAME_INVALID
)。
- 若证书缺少
subjectAltName
的常见类型
类型 | 示例 | 用途 |
---|---|---|
DNS | example.com | 保护普通域名 |
DNS | *.example.com | 保护通配符子域名 |
IP Address | 192.168.1.1 | 保护IP地址(如内网服务) |
email | user@example.com | 保护电子邮件地址(较少用) |
如何为自签证书添加 subjectAltName
?
方法1:使用 OpenSSL 配置文件(推荐)
- 创建配置文件
san.cnf
:[req] distinguished_name = req_distinguished_name x509_extensions = v3_req prompt = no[req_distinguished_name] CN = example.com # 传统字段(现代浏览器已忽略)[v3_req] subjectAltName = @alt_names[alt_names] DNS.1 = example.com DNS.2 = *.example.com IP.1 = 192.168.1.1
- 生成证书:
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \-keyout server.key -out server.crt -config san.cnf
方法2:命令行直接指定(OpenSSL 1.1.1+)
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \-keyout server.key -out server.crt -subj "/CN=example.com" \-addext "subjectAltName=DNS:example.com,DNS:*.example.com,IP:192.168.1.1"
验证证书是否包含 subjectAltName
openssl x509 -in server.crt -text -noout | grep -A 1 "Subject Alternative Name"
输出示例:
X509v3 Subject Alternative Name:DNS:example.com, DNS:*.example.com, IP Address:192.168.1.1
常见问题
-
浏览器仍报错“证书无效”?
- 确保证书已导入系统/浏览器信任库(见之前回答的步骤)。
- 检查
SAN
是否包含你访问的完整域名(如https://sub.example.com
需要DNS:sub.example.com
或DNS:*.example.com
)。
-
通配符
*
的限制?- 通配符仅匹配同级子域名(如
*.example.com
匹配a.example.com
,但不匹配a.b.example.com
)。
- 通配符仅匹配同级子域名(如
-
本地开发用
localhost
需要SAN
吗?- 需要!现代浏览器要求
localhost
也必须出现在SAN
中:[alt_names] DNS.1 = localhost IP.1 = 127.0.0.1
- 需要!现代浏览器要求
总结
subjectAltName
是必须的:现代证书必须通过它指定有效域名/IP,否则浏览器会拒绝连接。- 自签证书注意事项:生成时务必包含
SAN
,并手动信任证书(本地开发可行,生产环境请用受信任CA)。
以下是使用 OpenSSL 生成自签证书(含 subjectAltName
扩展,支持域名 www.jadl.com
)的完整步骤:
1. 创建 OpenSSL 配置文件(推荐方式)
新建文件 san.cnf
,内容如下:
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no[req_distinguished_name]
CN = www.jadl.com # 传统字段(现代浏览器已忽略,但建议填写)[v3_req]
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names # 关键:启用SAN扩展[alt_names]
DNS.1 = www.jadl.com # 主域名
DNS.2 = jadl.com # 可选:同时保护根域名
# IP.1 = 192.168.1.1 # 可选:如需IP访问可取消注释
2. 生成自签证书
执行以下命令(需 OpenSSL 1.1.1+):
openssl req -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes \-keyout www.jadl.com.key -out www.jadl.com.crt -config san.cnf
参数说明:
-x509
:生成自签证书(非CSR)。-newkey rsa:2048
:创建2048位RSA密钥。-sha256
:使用SHA-256签名算法。-days 3650
:证书有效期10年(按需调整)。-nodes
:密钥不加密(无密码)。-config san.cnf
:指定配置文件(含SAN)。
3. 验证证书内容
检查是否包含 subjectAltName
:
openssl x509 -in www.jadl.com.crt -text -noout | grep -A 1 "Subject Alternative Name"
预期输出:
X509v3 Subject Alternative Name:DNS:www.jadl.com, DNS:jadl.com
4. 部署证书
将生成的文件用于Web服务器:
- 私钥文件:
www.jadl.com.key
- 证书文件:
www.jadl.com.crt
示例(Nginx配置片段):
server {listen 443 ssl;server_name www.jadl.com;ssl_certificate /path/to/www.jadl.com.crt;ssl_certificate_key /path/to/www.jadl.com.key;
}
5. 手动信任证书(仅限本地/测试)
Windows:
- 双击
.crt
文件 → 点击“安装证书” → 选择“本地计算机” → 存入“受信任的根证书颁发机构”。
macOS/Linux:
# macOS
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain www.jadl.com.crt# Linux (Ubuntu)
sudo cp www.jadl.com.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
注意事项
- 浏览器警告:自签证书仍需手动信任,否则会显示“不安全”。
- 生产环境:请使用 Let’s Encrypt 等免费CA签发证书。
- 通配符域名:如需
*.jadl.com
,在san.cnf
中添加DNS.3 = *.jadl.com
。
一键生成脚本(无配置文件)
openssl req -x509 -newkey rsa:2048 -sha256 -days 3650 -nodes \-keyout www.jadl.com.key -out www.jadl.com.crt \-subj "/CN=www.jadl.com" \-addext "subjectAltName=DNS:www.jadl.com,DNS:jadl.com"
按此步骤操作后,证书将兼容所有现代浏览器。