在 Windows 上导入证书(受信任的根证书颁发机构)
将生成的 server.crt 拷贝到 Windows 电脑,然后按以下步骤操作:
双击 server.crt 文件,打开证书对话框
点击 “安装证书”,启动证书导入向导
选择 “本地计算机”(需要管理员权限),点击下一步
选择 “将所有的证书放入下列存储”,点击 浏览
在弹出的窗口中选择 “受信任的根证书颁发机构”,确定
点击下一步 → 完成,导入成功后会出现“导入成功”提示
重启浏览器(或清除 SSL 缓存),访问 https://example.com,地址栏应显示安全锁
让OpenSSL按照配置文件生产证书
以给example.com生产证书为例
touch example.com.ini
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| # ============================================ # OpenSSL 配置文件(涵盖所有命令行参数) # 使用方法: # 生成加密私钥 # openssl genrsa -aes256 -out example.com.key 2048 # 使用加密私钥生成自签名证书 # openssl req -x509 -utf8 -days 3650 -key example.com.key -out example.com.crt -config example.com.ini # 不使用加密私钥生成自签名证书 # openssl req -x509 -utf8 -days 3650 -out example.com.crt -config example.com.ini # (-utf8 必须加,否则中文 DN 会被按 Latin-1 二次编码而乱码;OpenSSL 3.x 忽略配置里的 default_days,请用 -days 显式指定有效期) # ============================================
[req] # 替代 -newkey rsa:2048 :指定生成的密钥类型和长度 default_bits = 2048 # 替代 -keyout /path/to/key :指定私钥保存路径(无需再敲 -keyout) default_keyfile = example.com.key # 替代 -nodes :不加密私钥(即不设置密码保护),值为 no 表示不加密 encrypt_key = no # 替代 -days 3650 :证书有效期(天) default_days = 3650 # 注意:string_mask 只决定证书里字符串的 ASN.1 类型(强制 UTF8STRING), # 并不能替代命令行的 -utf8 标志;不加 -utf8 时配置值会被当作 Latin-1 再编码而乱码 string_mask = utf8only # 指定摘要算法(比默认的 SHA1 更安全,命令行无此参数,但强烈建议加) default_md = sha256 # 使用下面的 [req_distinguished_name] 段 distinguished_name = req_distinguished_name # 使用下面的 [v3_req] 段定义扩展属性 x509_extensions = v3_req # 不弹出交互式输入,完全读取配置文件 prompt = no # ============================================ # 证书主体识别信息(DN) # ============================================ [req_distinguished_name] # 国家(Country) C = CN # 省/州(State or Province) ST = Shanghai # 城市(Locality) L = Shanghai # 组织名称(Organization) O = example # 部门名称(Organizational Unit) OU = 技术部 # 通用名称(Common Name),建议与主域名一致 CN = example.com
# ============================================ # 证书扩展属性(v3 扩展) # ============================================ [v3_req] # 密钥用途(Key Usage):声明证书的密钥可以执行哪些操作 # - digitalSignature :数字签名(用于 TLS 密钥交换中的签名验证) # - keyEncipherment :加密密钥(用于 RSA 密钥传输) # - dataEncipherment :加密数据(较少使用,但保留无害) keyUsage = digitalSignature, keyEncipherment, dataEncipherment
# 扩展密钥用途(Extended Key Usage):限定证书的具体服务类型 # - serverAuth :仅用于 TLS 服务器身份验证(即 HTTPS 服务) extendedKeyUsage = serverAuth
# 基本约束(Basic Constraints):声明该证书不是 CA(证书颁发机构),防止被滥用 basicConstraints = CA:FALSE
# 主体备用名称(Subject Alternative Name, SAN): # 这是现代浏览器和客户端实际验证的字段,必须包含所有访问方式。 subjectAltName = @alt_names
# ============================================ # SAN 列表(根据你的实际环境修改) # ============================================ [alt_names] # 域名(至少包含一个,且与访问地址完全匹配) # 你的主域名 DNS.1 = example.com IP.1 = 192.168.0.1 # 如果用户可能通过 IP 访问,请务必添加以下行(替换为你的服务器实际内网 IP) # IP.1 = 192.168.1.10 # 示例内网 IP,请取消注释并修改 # IP.2 = 127.0.0.1 # 本地回环(可选)
|
1、如果不需要给私钥加密
1
| openssl req -x509 -utf8 -days 3650 -out example.com.crt -config example.com.ini
|
2、需要给私钥加密
1 2
| openssl genrsa -aes256 -out example.com.key 2048 openssl req -x509 -utf8 -days 3650 -key example.com.key -out example.com.crt -config example.com.ini
|
把证书给NGINX代理
编辑nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| server { listen 80; server_name example.com; # 将 HTTP 请求重定向到 HTTPS return 301 https://$server_name$request_uri; }
server { listen 443 ssl http2 server_name example.com;
# ===== SSL 证书配置 ===== # 请将以下路径替换为你用 OpenSSL 生成的实际证书路径 ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key;
# ===== SSL 安全加固 ===== ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305; ssl_prefer_server_ciphers on; ssl_ecdh_curve X25519:prime256v1:secp384r1; ssl_session_cache shared:SSL:10m; ssl_session_timeout 4h; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 valid=300s; add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always; add_header X-Content-Type-Options nosniff always; add_header X-Frame-Options SAMEORIGIN always;
# ===== 根路径 ===== location / { root /opt/www/example.com; index index.html; } }
|