HTTPS和HTTP的协议区别

文章导读
HTTPS 和 HTTP 在语义层是同一套东西,区别在于 HTTPS 把 HTTP 报文放进 TLS 里传输。所以“要不要上 HTTPS”不是性能偏好问题,而是三件事的判断:数据是否需要防窃听和防篡改、链路是否经过不可信网络、证书续期是否有人负责。任何一条成立,就该走 HTTPS;本机调试或完全隔离的链路,可以先用裸 HTTP 排查问题。
📋 目录
  1. Ⅰ HTTP和HTTPS协议:各自站在什么位置
  2. Ⅱ HTTP和HTTPS协议:性能、成本、运维、上手四个口径分开比
  3. Ⅲ HTTP和HTTPS协议:什么情况选哪一边
  4. Ⅳ HTTP和HTTPS协议:一次能复现的对比做法
A A

HTTPS 和 HTTP 在语义层是同一套东西,区别在于 HTTPS 把 HTTP 报文放进 TLS 里传输。所以“要不要上 HTTPS”不是性能偏好问题,而是三件事的判断:数据是否需要防窃听和防篡改、链路是否经过不可信网络、证书续期是否有人负责。任何一条成立,就该走 HTTPS;本机调试或完全隔离的链路,可以先用裸 HTTP 排查问题。

协议差异只有一条:HTTPS 在 HTTP 与 TCP 之间加了一层 TLS,多一次握手和一次证书校验。选择判断落在三件事:数据是否需要防窃听篡改、链路是否经过不可信网络、证书续期有没有人盯。任何一条为是就走 HTTPS;纯本机或完全隔离的调试链路可以先 HTTP,但必须限定只监听回环地址,排查结束就撤掉,不要留成长期入口。

HTTP和HTTPS协议:各自站在什么位置

HTTP 是明文的应用层协议,报文格式和语义由 RFC 9110(HTTP Semantics)定义,可核对的位置是 IETF 站点上该 RFC 的 Message Format 与 Header Fields 章节。它的强项是链路透明:curl、tcpdump 抓下来就能看到请求行、头部和正文,出问题时定位成本最低。判断当前链路是不是纯 HTTP,可以用 curl -v http://目标/,输出里只有请求行、请求头和响应头,没有 TLS 握手段落。

HTTPS 是 HTTP 语义跑在 TLS 之上,TLS 1.3 的规范是 RFC 8446,TLS 1.2 是 RFC 5246,核对位置同样是 IETF 站点。它的强项是把传输内容变成不可读的密文,并让客户端能验证“对面确实是这个域名”。判断一条链路是否真的完成了 HTTPS,不要只看端口是 443,用 openssl s_client -connect 域名:443 -servername 域名 ,看输出的 Protocol 是不是 TLSv1.2 / TLSv1.3,以及 Verify return code 是否为 0 (ok)。端口只是约定,协议要看握手结果。

HTTP和HTTPS协议:性能、成本、运维、上手四个口径分开比

性能

HTTPS 多出来的是 TLS 握手往返和加解密计算,HTTP 没有这一段。量法是把 curl 的计时拆开:curl -sS -o /dev/null -w 'tcp=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}\n' URL。HTTP 请求里 tls 字段恒为 0,HTTPS 请求里该字段有值,差的就是握手成本。想做多连接握手压测可以用 openssl s_time -connect 域名:443 -new -time 5,它按时间窗口统计新建连接数。注意长连接、TLS 会话复用、HTTP/2 多路复用都会改变结论,单次 curl 的差值不能直接外推。

HTTPS和HTTP的协议区别

成本

HTTP 没有证书成本;HTTPS 有证书费用和续期工作量。证书价格和有效期属于会变的项,需要看证书颁发机构当期价格页和 ACME 客户端文档说明,不要按旧印象估算。建议的动作是先确认是否能用 ACME 免费签发,再评估通配符、多域名、OV/EV 类型的必要性。验证方式是签发后在目标机上跑一次续期演练:certbot renew --dry-run 或对应 ACME 客户端的 dry-run 子命令,确认自动续期真的能跑通。

运维

HTTP 的运维面很小,改配置重启即可。HTTPS 额外要盯四件事:证书到期时间、证书链是否完整、域名与 SAN 是否匹配、HTTP 入口是否统一跳转到 HTTPS。openssl s_client -connect 域名:443 -servername 域名 -showcerts 能看到服务端下发的整条链,链里缺中间证书时,浏览器可能“能打开”,但部分命令行客户端和移动端会直接失败。

上手

HTTP 一条命令就能起服务:python3 -m http.server 8080 --bind 127.0.0.1。HTTPS 至少要多一步证书准备,本地验证可以用自签证书:openssl req -x509 -newkey rsa:2048 -nodes -keyout /tmp/k.pem -out /tmp/c.pem -days 1 -subj '/CN=127.0.0.1'。自签证书只适合本地,因为它没有可信 CA 背书,客户端必然报警告,这个警告恰恰说明校验在工作,不是配置错误。

HTTP和HTTPS协议:什么情况选哪一边

面向公网、带登录或提交表单的服务,选 HTTPS。前置条件是证书链完整、域名与 SAN 匹配、HTTP 入口 301 到 HTTPS。很多浏览器能力也只在安全上下文可用,比如剪贴板写入、地理位置、Service Worker,用 HTTP 打开会直接拿不到。验证方式见上一节的 openssl s_client 与 curl 不带 -k 的请求。

HTTPS和HTTP的协议区别

本机调试、单机脚本、完全隔离的受控网段,可以先用 HTTP。前置条件明确写死:只监听回环地址(如上面的 --bind 127.0.0.1),不带真实用户凭证,排查完立即停掉。一旦这条链路要跨不可信网络,或者要与外部系统联调,就换回 HTTPS。

老设备或嵌入式服务只支持 HTTP,选在它前面加一层反向代理终止 TLS。前置条件是代理与后端在同一主机或同一受控网段,且代理到后端这一段不再经过不可信网络。这种做法的边界要说清:TLS 只覆盖到代理,代理之后仍是明文,不能当成端到端加密。

判断顺序建议按这个清单走:① 这条链路是否经过不可信网络 → 是则 HTTPS;② 是否传输凭证、令牌、个人数据 → 是则 HTTPS;③ 客户端是否依赖安全上下文才能工作的浏览器能力 → 是则 HTTPS;④ 是否能自动续期并有到期监控 → 否则先把续期跑通再上线;⑤ 以上都不成立且仅本机可达 → 可临时用 HTTP,并限制监听地址。

HTTPS和HTTP的协议区别

HTTP和HTTPS协议:一次能复现的对比做法

本机十分钟能跑完的对比:起一个纯 HTTP 服务和一个自签 TLS 服务,用同一套 curl 计时模板请求两者,看输出字段差异。

# 终端 1:纯 HTTP,只监听回环
python3 -m http.server 8080 --bind 127.0.0.1

# 终端 2:自签证书 + TLS 服务
openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout /tmp/k.pem -out /tmp/c.pem -days 1 -subj '/CN=127.0.0.1'
openssl s_server -accept 8443 -cert /tmp/c.pem -key /tmp/k.pem -www -quiet

# 终端 3:同一模板分别测两边
curl -sS -o /dev/null -w 'tcp=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}\n' http://127.0.0.1:8080/
curl -sSk -o /dev/null -w 'tcp=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}\n' https://127.0.0.1:8443/

预期差异在两处:HTTP 那行 tls 恒为 0.000000,HTTPS 那行 tls 有值,且 total 比 HTTP 多出握手这一段;另外 curl -sSk 之所以要加 -k,是因为自签证书不被信任,去掉 -k 会直接报证书校验失败。回环地址的握手耗时极低,这组数字只能用来看“差在哪里”,不能拿来估算公网环境的比例。

最容易踩的坑:用 curl -k 或浏览器里点“继续访问”完成验收,把证书链缺失、域名与 SAN 不匹配的问题藏起来。这类问题在部分客户端上会表现为直接连接失败,而验收时看不出来。可执行的校验方式是去掉 -k 再请求一次,并用 openssl s_client -connect 域名:443 -servername 域名 -showcerts 确认输出里有完整证书链、Verify return code 为 0 (ok)。