手把手教你用OpenSSL生成带SAN扩展的证书,彻底解决Chrome浏览器NET::ERR_CERT_COMMON_NAME_INVALID报错
彻底解决Chrome证书错误:OpenSSL生成SAN扩展证书全指南
每次在本地开发环境启动HTTPS服务时,那个刺眼的红色警告页面是否让你抓狂?"您的连接不是私密连接"、"NET::ERR_CERT_COMMON_NAME_INVALID"——这些错误正在拖慢你的开发效率。本文将揭示这些警告背后的真相,并提供一个完整的解决方案。
1. 为什么现代浏览器拒绝你的自签证书
2017年之后,Chrome等主流浏览器对证书验证实施了更严格的标准。传统自签证书只包含Common Name(CN)字段,而现代浏览器要求证书必须包含**Subject Alternative Name(SAN)**扩展。这就是为什么即使你正确生成了证书,浏览器仍然报错的原因。
SAN扩展的本质是让一个证书可以支持多个域名和IP地址。想象一下,你的开发环境可能需要:
- 本地访问的localhost
- 局域网IP如192.168.1.100
- 自定义域名如dev.example.com
传统证书只能选择一个作为CN,而SAN扩展允许你全部包含。下表展示了新旧证书的关键差异:
| 特性 | 传统证书 | 带SAN扩展证书 |
|---|---|---|
| 浏览器兼容性 | Chrome 58+报错 | 全版本兼容 |
| 支持的标识类型 | 仅CN | 多域名、多IP |
| 开发便利性 | 需反复生成证书 | 一次配置长期使用 |
| 安全性 | 基础验证 | 增强验证 |
2. 环境准备与OpenSSL配置
2.1 获取OpenSSL工具
Windows用户推荐使用官方编译版本:
# 下载地址(示例): https://slproweb.com/products/Win32OpenSSL.html安装后验证版本:
openssl version2.2 关键目录结构
建议创建以下目录结构管理证书文件:
/ssl /ca # CA根证书相关 /servers # 服务器证书 /ext # 扩展配置文件2.3 配置openssl.cnf
找到OpenSSL安装目录下的openssl.cnf文件,确保包含以下关键段落:
[ v3_ca ] basicConstraints = critical,CA:TRUE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment3. 创建带SAN扩展的CA根证书
3.1 生成CA私钥
使用AES-256加密保护你的根密钥:
openssl genrsa -aes256 -out ca/ca.key 2048注意:此处设置的密码务必牢记,后续签发服务器证书时需要验证
3.2 创建CA根证书
生成有效期为10年的CA证书:
openssl req -x509 -new -nodes -key ca/ca.key -sha256 -days 3650 \ -out ca/ca.crt -subj "/C=CN/ST=Shanghai/L=Shanghai/O=DevOrg/OU=IT/CN=DevRootCA"关键参数说明:
-x509:直接生成自签名证书-nodes:不加密私钥(可选)-sha256:使用更安全的哈希算法-days 3650:10年有效期
4. 生成带SAN扩展的服务器证书
4.1 创建扩展配置文件
在/ext目录创建server.ext文件:
authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment subjectAltName=@alt_names [alt_names] DNS.1=localhost DNS.2=dev.example.com IP.1=127.0.0.1 IP.2=192.168.1.1004.2 生成服务器私钥和CSR
首先生成私钥:
openssl genrsa -out servers/server.key 2048然后创建证书签名请求(CSR):
openssl req -new -key servers/server.key -out servers/server.csr \ -subj "/C=CN/ST=Shanghai/L=Shanghai/O=DevOrg/OU=Web/CN=dev.example.com"4.3 使用CA签发服务器证书
关键步骤——应用SAN扩展:
openssl x509 -req -in servers/server.csr -CA ca/ca.crt -CAkey ca/ca.key \ -CAcreateserial -out servers/server.crt -days 825 -sha256 \ -extfile ext/server.ext5. 在开发环境中应用证书
5.1 安装CA根证书
将ca.crt导入到系统的受信任根证书存储:
- Windows:双击.crt文件 → 安装证书 → 选择"受信任的根证书颁发机构"
- macOS:钥匙串访问 → 添加证书 → 标记为始终信任
5.2 配置Web服务器
以Nginx为例:
server { listen 443 ssl; server_name dev.example.com; ssl_certificate /path/to/server.crt; ssl_certificate_key /path/to/server.key; # 启用HTTP/2 listen 443 ssl http2; }5.3 测试证书有效性
使用OpenSSL验证:
openssl verify -CAfile ca/ca.crt servers/server.crt检查SAN信息:
openssl x509 -in servers/server.crt -text -noout | grep -A1 "Subject Alternative Name"6. 高级技巧与故障排除
6.1 通配符SAN配置
在server.ext中添加:
DNS.3=*.dev.example.com6.2 证书链验证问题
如果遇到中间证书问题,可以合并证书:
cat servers/server.crt ca/ca.crt > servers/fullchain.crt6.3 常见错误解决方案
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| ERR_CERT_AUTHORITY_INVALID | CA证书未安装 | 检查CA是否导入到信任存储 |
| ERR_CERT_COMMON_NAME_INVALID | SAN配置缺失 | 重新生成带SAN扩展的证书 |
| SSL_ERROR_BAD_CERT_DOMAIN | 域名不匹配 | 检查SAN中的DNS条目 |
7. 自动化脚本示例
创建gen_cert.sh自动化流程:
#!/bin/bash # 定义变量 DOMAIN="dev.example.com" IP="192.168.1.100" DAYS=825 # 生成SAN扩展文件 cat > ext/server.ext << EOF authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment subjectAltName=@alt_names [alt_names] DNS.1=localhost DNS.2=$DOMAIN IP.1=127.0.0.1 IP.2=$IP EOF # 生成服务器证书 openssl req -new -nodes -newkey rsa:2048 -keyout servers/server.key \ -out servers/server.csr -subj "/CN=$DOMAIN" openssl x509 -req -sha256 -days $DAYS -in servers/server.csr \ -CA ca/ca.crt -CAkey ca/ca.key -CAcreateserial \ -out servers/server.crt -extfile ext/server.ext echo "证书生成完成!"记得在实际项目中,我会把常用域名和IP预先配置在模板中,这样新项目只需简单修改几个参数就能快速生成合规证书。对于团队开发,建议将CA证书和安装说明纳入项目文档,确保每位成员都能正确配置本地环境。
