一、HTTPS 与 HTTP/2 核心原理与优势
在企业项目开发中,HTTP 协议的明文传输缺陷的是数据安全的重大隐患,而 HTTPS + HTTP/2 是目前企业级项目的标准安全+性能组合方案,先搞懂底层逻辑,再落地配置,避免踩坑。
1.1 HTTP 的致命缺陷
HTTP 协议采用明文传输,在数据从客户端到服务器的传输过程中,存在3大核心安全问题,完全无法满足企业等保2.0、用户隐私合规要求:
-
• 窃听风险:数据明文传输,中间人可直接抓包获取敏感信息(如账号密码、手机号、交易数据);
-
• 篡改风险:中间人可修改传输数据(如篡改订单金额、接口返回结果),导致业务异常;
-
• 劫持风险:中间人可劫持请求,跳转到恶意网站,造成用户信息泄露、财产损失。
1.2 HTTPS 核心原理
HTTPS(Hyper Text Transfer Protocol Secure)并非全新协议,而是 HTTP + TLS/SSL 协议 的组合,核心作用是"加密传输、身份认证、防篡改",本质是在 HTTP 传输层之上增加了一层 SSL/TLS 加密层。
HTTPS 加密流程:
-
- 客户端发起 HTTPS 请求,向服务器索要 SSL 证书;
-
- 服务器返回自身的 SSL 证书(包含公钥、服务器身份信息);
-
- 客户端验证证书合法性(是否过期、是否被篡改、是否由权威机构颁发);
-
- 验证通过后,客户端生成随机密钥,用服务器公钥加密后发送给服务器;
-
- 服务器用自身私钥解密,得到随机密钥;
-
- 双方后续所有通信,均使用该随机密钥进行对称加密,实现明文转密文传输。
关键说明:SSL 与 TLS 本质是同一类协议,TLS 是 SSL 的升级版本(目前主流使用 TLS 1.2/TLS 1.3,已淘汰 SSL 3.0)。
1.3 HTTPS 核心作用
-
• 传输加密:所有数据均为密文传输,中间人无法破解;
-
• 身份认证:通过 SSL 证书确认服务器真实身份,防止钓鱼网站;
-
• 防篡改:数据传输过程中会进行校验,一旦被篡改,客户端会立即识别;
-
• 合规要求:满足等保2.0、GDPR等隐私合规标准,企业项目必配。
1.4 HTTP/2 核心优势
HTTP/2 是 HTTP 协议的重大升级,必须基于 HTTPS 才能启用(主流浏览器仅支持 HTTPS 下的 HTTP/2),核心解决 HTTP 1.1 的性能瓶颈,优势如下:
-
• 多路复用:一个 TCP 连接可并发处理多个 HTTP 请求,避免 HTTP 1.1 的"队头阻塞"问题,大幅提升并发性能;
-
• 头部压缩:对 HTTP 请求头进行 HPACK 压缩,减少传输体积(尤其适合频繁请求的接口);
-
• 二进制分帧:将请求/响应数据拆分为二进制帧传输,解析速度比 HTTP 1.1 的文本格式更快;
-
• 服务器推送:服务器可提前推送客户端可能需要的资源(如静态文件),减少请求次数,提升页面加载速度;
-
• 优先级设置:可给不同请求设置优先级,确保核心接口(如支付、登录)优先响应。
实测对比:HTTP/2 比 HTTP 1.1 接口响应速度提升 30%-50%,高并发场景下优势更明显。
二、SSL 证书详解与生成
SSL 证书是 HTTPS 实现的核心,相当于服务器的"身份凭证",分为「自签名证书」(本地测试用)和「权威机构证书」(生产用),两者区别、生成方法、使用场景全部讲透。
2.1 SSL 证书类型对比
| 证书类型 | 适用场景 | 优势 | 劣势 |
|---|---|---|---|
| 自签名证书 | 本地开发、测试环境 | 免费、生成快速、无需审核 | 无权威机构认证,浏览器提示"不安全" |
| 权威机构免费证书 | 个人项目、小型企业、测试环境 | 免费、权威认证、浏览器信任 | 有效期短(通常1年)、仅支持单域名 |
| 权威机构付费证书 | 生产环境、企业项目、多域名场景 | 有效期长、多域名支持、更高安全等级、售后保障 | 需要付费、审核严格 |
生产环境推荐:阿里云、腾讯云申请免费权威证书(如 Let's Encrypt、阿里云免费 SSL),足够满足大部分企业需求;大型企业、多域名场景可选择付费证书。
2.2 方式1:本地测试用自签名证书
本地开发无需权威证书,使用 JDK 自带的 keytool 工具即可快速生成,步骤如下(全程复制命令,无需修改):
-
- 打开终端(Windows 用 CMD/PowerShell,Mac/Linux 用终端);
-
- 进入 JDK 的 bin 目录(若配置了 JDK 环境变量,可直接在任意目录执行);
-
- 执行生成命令(密码统一设置为 123456,方便后续配置):
go
keytool -genkey -alias tomcat -keyalg RSA -keysize 2048 -validity 3650 -keystore server.jks
命令参数说明:
-
• -genkey:生成密钥对;
-
• -alias tomcat:证书别名(后续配置需要用到,可自定义,建议保持 tomcat);
-
• -keyalg RSA:加密算法(主流 RSA,安全性足够);
-
• -keysize 2048:密钥长度(2048位及以上,安全性更高);
-
• -validity 3650:证书有效期(单位:天,3650天=10年,本地测试足够);
-
• -keystore server.jks:生成的证书文件名及格式(JKS 是 Java 常用格式)。
执行命令后,会提示输入姓名、组织、城市等信息,全部随便输入即可(本地测试无需真实信息),最后确认"是",即可生成 server.jks 文件。
将生成的 server.jks 文件,复制到 SpringBoot 项目的 resources 目录下(直接放在根目录,无需创建子文件夹)。
2.3 方式2:生产环境权威证书
生产环境必须使用权威机构颁发的证书,否则浏览器会提示"不安全",影响用户信任,这里以阿里云为例,讲解免费证书的申请与下载流程(腾讯云流程类似):
-
- 登录阿里云控制台,搜索"SSL证书",进入证书管理页面;
-
- 点击"申请证书",选择"免费证书"(Let's Encrypt 或阿里云免费版),点击"立即申请";
-
- 填写域名信息(如 www.xxx.com),验证域名所有权(推荐 DNS 验证,操作最简单);
-
- 验证通过后,等待 1-10 分钟,证书即可颁发;
-
- 证书颁发后,点击"下载",选择"JKS"格式(SpringBoot 原生支持,若用 Nginx 部署,可选择 PEM 格式);
-
- 下载后会得到两个文件:xxx.jks(证书文件)和 keystorePassword.txt(证书密码),将 xxx.jks 重命名为 server.jks(方便配置),复制到项目 resources 目录下。
注意:生产证书有效期通常为 1 年,到期前需提前续期(阿里云会有提醒,续期流程和申请一致,免费续期)。
2.4 证书格式说明
SpringBoot 支持多种 SSL 证书格式,核心两种:
-
• JKS:Java 原生格式,无需额外依赖,直接配置即可使用(推荐);
-
• PFX:Windows 常用格式,兼容性更强,若使用 PFX 证书,需修改配置文件中的 key-store-type 为 PFX,同时配置 key-store-password(证书密码)和 key-password(私钥密码,通常与证书密码一致)。
三、SpringBoot 开启 HTTPS + HTTP/2
SpringBoot 2.0+ 对 HTTPS 和 HTTP/2 提供了原生支持,无需额外引入依赖,仅需简单配置即可开启,全程复制代码,一步到位。
3.1 pom.xml 依赖
SpringBoot Web 依赖已内置 Tomcat 容器和 SSL 相关组件,无需额外引入依赖,核心依赖如下:
go
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version> <!-- 与全系列版本统一 -->
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-https-http2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-https-http2</name>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- Web 核心依赖,内置 Tomcat、Jackson、SSL 组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Lombok 简化代码(可选,与全系列风格统一) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
3.2 application.yml 核心配置
配置 HTTPS 端口、SSL 证书、HTTP/2,注释详细,可直接复制,仅需修改证书密码(生产环境替换为自己的证书密码):
go
server:
# HTTPS 默认端口:443(生产环境必须用443,浏览器可省略端口访问)
port: 443
# 开启 HTTP/2 协议(必须基于 HTTPS 才能生效)
http2:
enabled: true
# SSL 证书核心配置
ssl:
enabled: true # 开启 SSL 加密(即开启 HTTPS)
key-store: classpath:server.jks # 证书文件路径(resources 目录下)
key-store-type: JKS # 证书格式(JKS 或 PFX,根据自己的证书修改)
key-store-password: 123456 # 证书密码(自签名证书是123456,生产证书是下载时的密码)
key-alias: tomcat # 证书别名(与生成证书时的 -alias 一致)
key-password: 123456 # 私钥密码(通常与证书密码一致,可省略,默认与 key-store-password 相同)
# 生产环境额外配置:强加密套件(提升安全性,避免弱加密被攻击)
ciphers: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
# 生产环境额外配置:禁用不安全的 TLS 版本(仅保留 TLS 1.2/TLS 1.3)
enabled-protocols: TLSv1.2,TLSv1.3
3.3 启动测试
-
- 启动 SpringBoot 项目,控制台无报错,说明配置成功;
-
- 打开浏览器,访问:
https://localhost(无需输入端口,443是默认端口);
- 打开浏览器,访问:
-
- 本地自签名证书:浏览器会提示"您的连接不是私密连接",点击"高级"→"继续访问"(正常现象,生产证书无此提示);
-
- 生产权威证书:浏览器地址栏会显示「小锁图标」,说明 HTTPS 生效。
四、HTTP 自动跳转 HTTPS
用户习惯输入 http://xxx.com(如 http://localhost),若不配置跳转,会提示无法访问,影响用户体验。企业项目必须配置:所有 HTTP 请求(80端口)自动 302 跳转到 HTTPS 请求(443端口),实现全站 HTTPS。
4.1 跳转配置类
SpringBoot 默认使用 Tomcat 容器,编写配置类,开启 80 端口监听,实现自动跳转,代码可直接复制:
go
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.apache.catalina.connector.Connector;
@Configuration
public class HttpToHttpsConfig {
/**
* 配置 HTTP 80 端口跳转 HTTPS 443 端口
*/
@Bean
public ServletWebServerFactory servletWebServerFactory() {
// 基于 Tomcat 容器配置
TomcatServletWebServerFactory tomcatFactory = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(org.apache.catalina.Context context) {
// 关闭 Tomcat 自身的 HTTP 缓存(可选,提升安全性)
org.apache.catalina.webresources.StandardRoot root = new org.apache.catalina.webresources.StandardRoot(context);
root.setCacheMaxSize(0);
context.setResources(root);
}
};
// 配置 HTTP 连接器(监听 80 端口)
Connector httpConnector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
httpConnector.setScheme("http"); // 协议类型
httpConnector.setPort(80); // HTTP 监听端口
httpConnector.setSecure(false); // 非安全连接(HTTP 无加密)
httpConnector.setRedirectPort(443); // 跳转目标端口(HTTPS 443 端口)
// 将 HTTP 连接器添加到 Tomcat 容器
tomcatFactory.addAdditionalTomcatConnectors(httpConnector);
return tomcatFactory;
}
}
4.2 跳转测试
-
- 重启 SpringBoot 项目(配置类修改后需重启);
-
- 打开浏览器,访问:
http://localhost(80端口);
- 打开浏览器,访问:
-
- 浏览器会自动跳转到
https://localhost,地址栏显示小锁图标,跳转成功。
- 浏览器会自动跳转到
4.3 注意事项
-
• 确保 80 端口未被其他程序占用(Windows 下可能被 IIS、迅雷等占用,需关闭对应程序);
-
• redirectPort 必须设置为 443(HTTPS 默认端口),否则会出现跳转死循环;
-
• 若使用 Jetty/Undertow 容器,需修改跳转配置(本文以 Tomcat 为例,主流企业项目均用 Tomcat)。
五、HTTP/2 开启验证与性能优化
HTTP/2 已在 application.yml 中配置 http2.enabled: true,但需验证是否真正生效,同时可做一些性能优化,发挥 HTTP/2 的最大优势。
5.1 HTTP/2 生效验证
方法1:Chrome 浏览器验证
-
- 访问
https://localhost,打开 Chrome 开发者工具(F12);
- 访问
-
- 切换到「Network」标签页,刷新页面;
-
- 查看「Protocol」列,若显示「h2」,说明 HTTP/2 开启成功;若显示「http/1.1」,说明未生效。
方法2:命令行验证
执行以下命令,查看响应头中的「HTTP/2」标识:
go
curl -I https://localhost
若输出中包含「HTTP/2 200」,说明 HTTP/2 生效。
方法3:在线工具验证
访问在线 HTTPS 检测工具(如 https://http2.pro/),输入自己的域名,工具会自动检测是否开启 HTTP/2,同时检测证书合法性、加密套件等。
5.2 HTTP/2 未生效的常见原因
-
• 未开启 HTTPS:HTTP/2 必须基于 HTTPS,先确保 HTTPS 正常访问;
-
• SpringBoot 版本过低:需 SpringBoot 2.4+(推荐 2.7.x,与全系列统一);
-
• JDK 版本过低:需 JDK 8u261+(JDK 8 低版本不支持 HTTP/2);
-
• 浏览器不支持:主流浏览器(Chrome、Firefox、Edge)均支持,IE 不支持 HTTP/2。
5.3 HTTP/2 性能优化
-
• 开启服务器推送:配置 Tomcat 开启服务器推送,提前推送静态资源(如 CSS、JS),减少请求次数;
-
• 启用头部压缩:HTTP/2 默认开启 HPACK 头部压缩,无需额外配置;
-
• 合并静态资源:虽然 HTTP/2 支持多路复用,但合并静态资源(如合并 CSS、JS)仍可减少请求数量,提升性能;
-
• 启用 Gzip 压缩:配置 SpringBoot 开启 Gzip 压缩,进一步减少传输体积。
Gzip 压缩配置(添加到 application.yml):
go
server:
compression:
enabled: true # 开启 Gzip 压缩
mime-types: text/html,text/xml,text/plain,application/json,application/javascript # 压缩类型
min-response-size: 1024 # 最小压缩体积(小于1KB不压缩)
六、生产环境最佳实践
本地配置完成后,生产环境部署需注意以下细节,避免安全漏洞、性能瓶颈,同时满足合规要求。
6.1 端口与证书配置
-
• 端口规范:HTTPS 用 443 端口,HTTP 用 80 端口,禁止使用非标准端口;
-
• 证书选型:使用权威机构免费/付费证书,禁止在生产环境使用自签名证书;
-
• 证书存储:生产环境证书不建议放在项目 resources 目录下,建议放在服务器独立目录(如 /usr/local/ssl),并设置权限(仅管理员可访问);
-
• 多域名支持:若项目有多个域名(如 www.xxx.com、api.xxx.com),需申请多域名证书,或配置多个 SSL 证书。
6.2 安全加固配置
(1)开启 HSTS 强制 HTTPS
HSTS(HTTP Strict Transport Security)强制浏览器只能通过 HTTPS 访问,即使用户输入 HTTP,也会直接跳转 HTTPS,避免中间人劫持,配置如下(添加到配置类):
go
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Configuration
public class WebSecurityConfig implements WebMvcConfigurer {
/**
* 开启 HSTS 强制 HTTPS
*/
@Bean
public Filter hstsFilter() {
return new Filter() {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
// max-age=31536000:HSTS 有效期1年,includeSubDomains:包含所有子域名
httpResponse.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
chain.doFilter(request, response);
}
};
}
}
(2)配置强加密套件
禁用弱加密套件(如 SSL 3.0、TLS 1.0/1.1),仅保留强加密套件,避免被攻击,配置已在 application.yml 中添加,再次强调:
go
server:
ssl:
ciphers: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
enabled-protocols: TLSv1.2,TLSv1.3
(3)关闭 Tomcat 版本泄露
Tomcat 会在响应头中泄露版本信息,可能被攻击者利用,配置关闭:
go
server:
tomcat:
server-header: "" # 清空服务器响应头,隐藏 Tomcat 版本
6.3 证书续期与备份
-
• 续期提醒:免费证书有效期1年,提前15-30天续期,避免证书过期导致服务不可用;
-
• 证书备份:下载证书后,备份证书文件和密码,避免丢失;
-
• 续期部署:续期后,替换服务器上的旧证书,重启项目即可,无需修改配置。
6.4 容器部署适配(Nginx + SpringBoot)
企业生产环境通常用 Nginx 反向代理 SpringBoot 项目,此时可将 HTTPS 配置在 Nginx 层面(推荐),SpringBoot 内部关闭 HTTPS,仅提供 HTTP 服务,流程如下:
-
- SpringBoot 配置:关闭 HTTPS,端口改为 8080(内部端口);
-
- Nginx 配置:开启 HTTPS、HTTP/2,配置 80 跳转 443,反向代理到 8080 端口;
-
- 优势:集中管理证书、支持负载均衡、提升并发性能。
Nginx 核心配置示例(参考):
go
server {
listen 80;
server_name www.xxx.com;
# HTTP 跳转 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name www.xxx.com;
# SSL 证书配置
ssl_certificate /usr/local/ssl/server.pem; # PEM 格式证书
ssl_certificate_key /usr/local/ssl/server.key; # 私钥
# 安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
# 反向代理到 SpringBoot 8080 端口
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
学习本就是一个长期积累的过程,没有捷径,唯有坚持。希望这些干货能够真正帮到你,学以致用,不断提升,在自己的领域里越走越远。喜欢本文,别忘了点赞、在看、转发,我们下期干货继续!