http与https的本质区别在于是否引入tls层:http明文传输走80端口,https在tcp与http间插入tls层走443端口,所有http报文均经tls加密后传输。

HTTP 和 HTTPS 的本质区别不是“有没有加密”,而是“有没有 TLS 层”
HTTP 是明文传输协议,走 80 端口;HTTPS 是 HTTP + TLS(过去叫 SSL),走 443 端口。关键不在“S”代表 secure,而在于它在 TCP 之上、HTTP 之下插入了一层 TLS 协议栈——所有 HTTP 报文都先被 TLS 加密后再发出去。面试时如果只答“HTTPS 加密了,HTTP 没有”,容易被追问:加密在哪一层?加的是什么?怎么加的?
TLS 握手阶段完成三件事:身份认证、密钥协商、加密套件确认
浏览器访问 https://example.com 后,TCP 连接建立后立刻开始 TLS 握手(不是等 HTTP 请求发出才开始)。这个过程实际决定了后续通信是否可信、用什么算法加密、密钥怎么生成。
- 服务器必须提供由可信 CA 签发的
X.509证书,浏览器验证域名、有效期、CA 链、吊销状态(OCSP 或 CRL) - 密钥交换不直接传对称密钥,而是用非对称加密保护“预主密钥”(Pre-Master Secret)——比如 RSA 方式下,客户端用证书里的公钥加密预主密钥;ECDHE 方式下则双方各自算出相同共享密钥,实现前向保密
- 双方用预主密钥 + 随机数派生出真正的对称密钥(如 AES-256-GCM 的密钥和 IV),后续 HTTP 数据全部用该密钥加密
HTTPS 并非全程“端到端加密”,中间设备可能解密(如企业代理、WAF)
很多候选人误以为只要 URL 是 https://,数据就绝对安全。实际上,TLS 加密只保证“客户端到第一个 TLS 终结点”之间的传输安全。如果公司部署了 HTTPS 解密代理,或用了云 WAF(如 Cloudflare 的 Flexible SSL),那么:
- 用户 → 代理之间是 HTTPS(浏览器显示锁图标)
- 代理 → 源站之间可能是 HTTP,也可能是另一段 HTTPS(但证书由代理控制)
- 代理可以查看、修改甚至重写原始 HTTP 请求头和响应体
Java 后端如果依赖 request.getRemoteAddr() 做风控,却没检查 X-Forwarded-For 或启用 RemoteIpFilter,就可能被伪造 IP 绕过。
立即学习“Java免费学习笔记(深入)”;
Java 中处理 HTTPS 常见疏漏点:信任库、主机名校验、ALPN 支持
用 HttpsURLConnection 或 OkHttpClient 调用 HTTPS 接口时,看似能通,但默认行为可能埋雷:
- 未显式设置
TrustManager时,JDK 默认信任$JAVA_HOME/jre/lib/security/cacerts里的 CA;若服务端证书是自签或私有 CA,会抛javax.net.ssl.SSLHandshakeException: PKIX path building failed - 禁用主机名校验(如 OkHttp 的
hostnameVerifier = (hostname, session) -> true)等于放弃证书绑定,极易遭受中间人攻击 - JDK 8u251+ 默认开启 ALPN(应用层协议协商),但某些老 Nginx 或 Spring Boot 内嵌 Tomcat 若未配好 HTTP/2,可能导致连接失败且错误日志不明确
System.setProperty("javax.net.debug", "ssl:handshake"); // 开启 TLS 握手日志,排查证书/协议问题最直接的方式
真正难的不是记住加密流程图,而是理解每一步在 Java 栈里对应哪个类、哪个配置项、哪条日志——比如 SSLContext.getInstance("TLSv1.3") 在 JDK 11 才默认可用,JDK 8 需要手动升级底层 provider。










