# HTTPS/SSL 使用文档

# 1. HTTPS/SSL 概述

HTTPS(HyperText Transfer Protocol Secure)是HTTP的安全版本,通过SSL(Secure Sockets Layer)或TLS(Transport Layer Security)协议提供加密通信和身份验证。HTTPS通过加密数据传输和验证服务器身份,保护用户与网站之间的通信安全。

# 1.1 主要特点

  • 数据加密:使用SSL/TLS协议加密传输的数据,防止中间人窃听
  • 身份验证:验证服务器身份,确保用户连接到正确的网站
  • 数据完整性:确保传输的数据不被篡改
  • 信任建立:通过数字证书建立用户与网站之间的信任关系

# 1.2 应用场景

  • 电子商务网站处理支付信息
  • 社交媒体和电子邮件服务
  • 在线银行和金融服务
  • 需要保护用户隐私的任何网站
  • API服务和微服务通信

# 2. SSL/TLS 工作原理

# 2.1 基本工作流程

  1. 客户端发起HTTPS请求:客户端(浏览器)向服务器发送HTTPS请求
  2. 服务器返回证书:服务器返回包含公钥的数字证书
  3. 客户端验证证书:客户端验证证书的有效性(颁发机构、有效期、域名匹配等)
  4. 客户端生成会话密钥:客户端生成随机会话密钥,使用服务器公钥加密
  5. 客户端发送加密的会话密钥:将加密后的会话密钥发送给服务器
  6. 服务器解密获取会话密钥:服务器使用私钥解密获取会话密钥
  7. 双方使用会话密钥加密通信:后续通信均使用对称加密的会话密钥进行加密

# 2.2 SSL/TLS 握手过程

Client                                            Server
  |                                                |
  |-------- ClientHello (支持的协议版本,            |
  |          加密套件, 随机数) --------------------->|  
  |                                                |
  |<----- ServerHello (选择的协议版本,              |
  |          加密套件, 随机数, 服务器证书) -----------|  
  |                                                |
  | (验证服务器证书)                                |
  |                                                |
  |-------- ClientKeyExchange (预主密钥) ----------->|  
  |        ChangeCipherSpec                        |
  |        Finished (使用协商的密钥加密) ------------->|  
  |                                                |
  |<----- ChangeCipherSpec                         |
  |<----- Finished (使用协商的密钥加密) --------------|  
  |                                                |
  |<=========== 加密的应用数据 ====================>|  
  |                                                |

# 2.3 加密套件

SSL/TLS支持多种加密套件,一个典型的加密套件包括:

  • 密钥交换算法(如RSA、ECDHE、DHE)
  • 身份验证算法(如RSA、ECDSA)
  • 对称加密算法(如AES、ChaCha20)
  • 消息认证码算法(如SHA-256、SHA-384)

示例:ECDHE-RSA-AES256-GCM-SHA384表示使用ECDHE进行密钥交换,RSA进行身份验证,AES-256-GCM进行对称加密,SHA-384进行消息认证。

# 3. 数字证书

# 3.1 证书类型

  • 域名验证证书(DV):仅验证域名所有权,安全性较低,颁发速度快
  • 组织验证证书(OV):验证域名所有权和组织信息,安全性中等
  • 扩展验证证书(EV):最高级别的验证,验证域名所有权、组织信息和法律存在,浏览器地址栏显示绿色和组织名称
  • 通配符证书:可用于一个域名及其所有子域名(如*.example.com)
  • 多域名证书(SAN):可用于多个不同的域名

# 3.2 证书格式

常见的证书格式包括:

  • PEM(Privacy Enhanced Mail):Base64编码的ASCII格式,后缀通常为.pem、.crt、.cer、.key
  • DER(Distinguished Encoding Rules):二进制格式,后缀通常为.der、.cer
  • PKCS#12:二进制格式,包含证书和私钥,后缀通常为.p12、.pfx
  • JKS(Java KeyStore):Java专用的密钥库格式

# 3.3 证书链

证书链由以下部分组成:

  • 终端实体证书:网站使用的证书
  • 中间证书:介于终端实体证书和根证书之间的证书
  • 根证书:由证书颁发机构(CA)颁发的自签名证书,已预装在浏览器中

证书验证过程会从终端实体证书开始,逐级验证到根证书。

# 4. HTTPS 配置示例

# 4.1 Nginx 配置

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    # SSL 证书配置
    ssl_certificate /path/to/fullchain.pem;  # 包含服务器证书和中间证书的完整证书链
    ssl_certificate_key /path/to/privkey.pem;  # 服务器私钥

    # SSL 优化配置
    ssl_protocols TLSv1.2 TLSv1.3;  # 只启用现代的TLS协议版本
    ssl_prefer_server_ciphers off;  # 让客户端选择最适合的加密套件
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
    ssl_session_timeout 1d;  # SSL会话缓存超时时间
    ssl_session_cache shared:SSL:10m;  # SSL会话缓存大小
    ssl_session_tickets off;  # 禁用会话票据

    # HSTS (HTTP Strict Transport Security)
    add_header Strict-Transport-Security "max-age=63072000" always;  # 告诉浏览器始终使用HTTPS

    # OCSP Stapling
    ssl_stapling on;  # 启用OCSP Stapling
    ssl_stapling_verify on;  # 验证OCSP响应
    resolver 8.8.8.8 8.8.4.4 valid=300s;  # DNS解析器
    resolver_timeout 5s;  # 解析器超时时间

    # 其他配置
    root /var/www/html;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

# HTTP重定向到HTTPS
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

# 4.2 Apache 配置

<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/html

    # SSL 证书配置
    SSLEngine on
    SSLCertificateFile /path/to/cert.pem
    SSLCertificateKeyFile /path/to/privkey.pem
    SSLCertificateChainFile /path/to/chain.pem

    # SSL 优化配置
    SSLProtocol -all +TLSv1.2 +TLSv1.3
    SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
    SSLHonorCipherOrder off
    SSLSessionTickets off
    SSLSessionCache shmcb:/var/run/apache2/ssl_scache(512000)
    SSLSessionCacheTimeout 300

    # HSTS
    Header always set Strict-Transport-Security "max-age=63072000"  # 2年

    # 其他配置
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

# HTTP重定向到HTTPS
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    Redirect permanent / https://example.com/
</VirtualHost>

# 4.3 Spring Boot 配置

在application.properties中配置

# SSL 配置
server.port=8443
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=your-password
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=tomcat
server.ssl.protocol=TLS
server.ssl.enabled-protocols=TLSv1.2,TLSv1.3

# HTTP到HTTPS的重定向
# 需要添加以下配置类

创建HTTP到HTTPS的重定向配置类

import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HttpsConfig {

    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint securityConstraint = new SecurityConstraint();
                securityConstraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                securityConstraint.addCollection(collection);
                context.addConstraint(securityConstraint);
            }
        };
        
        tomcat.addAdditionalTomcatConnectors(redirectConnector());
        return tomcat;
    }

    private Connector redirectConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        connector.setPort(8080);
        connector.setSecure(false);
        connector.setRedirectPort(8443);
        return connector;
    }
}

# 4.4 Docker 环境中的HTTPS配置

使用Nginx容器

FROM nginx:latest

# 复制证书文件到容器
COPY ./ssl/cert.pem /etc/nginx/ssl/cert.pem
COPY ./ssl/privkey.pem /etc/nginx/ssl/privkey.pem
COPY ./ssl/chain.pem /etc/nginx/ssl/chain.pem

# 复制Nginx配置文件
COPY ./nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 443 80

docker-compose.yml示例

version: '3'

services:
  web:
    build: .
    ports:
      - "443:443"
      - "80:80"
    volumes:
      - ./html:/var/www/html
      - ./ssl:/etc/nginx/ssl:ro

# 5. 证书管理

# 5.1 证书获取

# 5.1.1 从证书颁发机构(CA)获取

  1. 生成私钥和证书签名请求(CSR)
    openssl req -newkey rsa:2048 -nodes -keyout domain.key -out domain.csr
    
  2. 向CA提交CSR
  3. 完成验证过程
  4. 下载签发的证书

# 5.1.2 使用Let's Encrypt获取免费证书

Let's Encrypt是一个提供免费SSL/TLS证书的非营利性CA。可以使用Certbot工具自动化获取和更新证书。

安装Certbot

# Ubuntu/Debian
apt-get update
apt-get install certbot python3-certbot-nginx

# CentOS/RHEL
yum install certbot python3-certbot-nginx

获取证书(Nginx)

certbot --nginx -d example.com -d www.example.com

自动更新证书

# 测试自动更新
certbot renew --dry-run

# 设置定时任务(通常Certbot会自动设置)
crontab -e
# 添加以下行(每天凌晨2点运行更新检查)
0 2 * * * certbot renew --quiet

# 5.2 证书格式转换

PEM转PFX

openssl pkcs12 -export -out certificate.pfx -inkey private.key -in certificate.crt -certfile ca_bundle.crt

DER转PEM

openssl x509 -inform der -in certificate.der -out certificate.pem

PFX转PEM

openssl pkcs12 -in certificate.pfx -out certificate.pem -nodes

# 5.3 证书验证

检查证书信息

openssl x509 -in certificate.crt -text -noout

验证证书链

openssl verify -CAfile ca_bundle.crt certificate.crt

检查证书有效期

openssl x509 -in certificate.crt -dates -noout

在线验证工具:SSL Labs的SSL Server Test (https://www.ssllabs.com/ssltest/)

# 6. HTTPS 性能优化

# 6.1 启用HTTP/2

HTTP/2提供了多路复用、头部压缩等特性,可以显著提升HTTPS性能。

Nginx配置

listen 443 ssl http2;

Apache配置

Protocols h2 http/1.1

# 6.2 会话复用

SSL/TLS会话复用可以避免每次连接都进行完整的握手过程,从而提升性能。

Nginx配置

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;

Apache配置

SSLSessionCache shmcb:/var/run/apache2/ssl_scache(512000)
SSLSessionCacheTimeout 300

# 6.3 OCSP Stapling

OCSP Stapling允许服务器在TLS握手过程中提供证书的在线状态协议(OCSP)响应,避免客户端单独查询CA。

Nginx配置

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

Apache配置

SSLUseStapling on
SSLStaplingCache shmcb:/var/run/apache2/ssl_stapling(32768)

# 6.4 优化加密套件

选择高效的加密套件可以提升HTTPS性能。

推荐的现代加密套件

  • ECDHE-ECDSA-AES256-GCM-SHA384
  • ECDHE-RSA-AES256-GCM-SHA384
  • ECDHE-ECDSA-AES128-GCM-SHA256
  • ECDHE-RSA-AES128-GCM-SHA256

# 7. 安全最佳实践

# 7.1 配置安全的SSL/TLS参数

  • 禁用旧版本协议:禁用SSLv2、SSLv3和早期的TLS版本
  • 使用现代加密套件:优先选择支持前向保密的加密套件
  • 配置适当的密钥长度:推荐使用2048位或更长的RSA密钥,或256位的椭圆曲线密钥

# 7.2 实施HSTS

HTTP Strict Transport Security (HSTS) 告诉浏览器始终使用HTTPS连接网站。

配置HSTS

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

参数说明

  • max-age:HSTS策略的有效期(秒)
  • includeSubDomains:将HSTS策略应用到所有子域名
  • preload:允许将域名添加到浏览器预加载列表

# 7.3 启用证书透明度

证书透明度(Certificate Transparency)提供了一种监控和审计SSL/TLS证书的机制。

  • 许多现代浏览器要求新证书必须支持证书透明度
  • 可以使用证书透明度日志监控服务检测未授权的证书颁发

# 7.4 定期更新和轮换证书

  • 遵循最小权限原则,只使用必要的证书
  • 定期更换证书,即使证书尚未过期
  • 证书泄露时立即吊销并重新颁发
  • 建立证书生命周期管理流程

# 8. 常见问题与解决方案

# 8.1 证书警告

问题:浏览器显示证书警告

可能原因

  • 证书已过期
  • 证书域名与访问的域名不匹配
  • 证书颁发机构不被浏览器信任
  • 证书链不完整

解决方案

  • 检查并更新证书
  • 确保证书包含正确的域名
  • 使用受信任的CA颁发的证书
  • 确保证书链完整,包含所有中间证书

# 8.2 HTTPS性能问题

问题:启用HTTPS后网站加载速度变慢

解决方案

  • 启用HTTP/2
  • 配置SSL会话复用
  • 启用OCSP Stapling
  • 优化服务器响应时间
  • 使用CDN加速HTTPS内容分发

# 8.3 混合内容警告

问题:HTTPS页面包含HTTP资源,导致混合内容警告

解决方案

  • 将所有资源(图片、CSS、JavaScript等)从HTTP迁移到HTTPS
  • 使用相对协议URL(如//example.com/resource)
  • 使用内容安全策略(CSP)阻止混合内容

# 8.4 证书吊销问题

问题:证书吊销列表(CRL)或OCSP响应不可用

解决方案

  • 配置适当的DNS解析器
  • 增加OCSP响应超时时间
  • 考虑使用OCSP Stapling
  • 对于关键服务,实施备用验证机制

# 9. 参考资源