计算机网络:HTTPS 和 HTTP 的区别是什么?

#计算机网络#操作系统#面试八股

计算机网络:HTTPS 和 HTTP 的区别是什么?

结论:HTTPS 不是另起炉灶的新协议,而是 HTTP over TLS:在 TCP 与 HTTP 之间插入 TLS 记录层, 为报文提供机密性、完整性和服务端身份认证,默认端口 443。HTTP 是明文,链路上任何一跳都能读、能改。

1. 一张表看差异

维度HTTPHTTPS
传输内容明文TLS 加密后的密文
默认端口80443
身份认证无证书链校验服务端身份
完整性无(仅 TCP 校验和)AEAD 认证标签,防篡改
中间设备可见全部内容基本只有 SNI 与目标 IP
性能开销无握手 1~2 个 RTT + 加解密(有硬件加速后很小)
浏览器态度地址栏标"不安全"锁标;部分 API 仅 HTTPS 可用

证书本身只是"公钥 + 身份 + CA 签名",真正加密业务数据的仍是握手协商出的对称密钥。

2. 握手过程

TLS 1.2 需要两个往返:

客户端                                          服务端
  |-- ClientHello(版本/随机数/套件/SNI)-------->|
  |<-- ServerHello(随机数/套件)+ Certificate ---|
  |<-- ServerKeyExchange + ServerHelloDone ------|
  |-- ClientKeyExchange + ChangeCipherSpec ----->|
  |-- Finished --------------------------------->|
  |<-- ChangeCipherSpec + Finished --------------|

TLS 1.3 把密钥交换提前,压缩成一个往返,会话恢复时还能 0-RTT:

客户端                                          服务端
  |-- ClientHello + key_share ------------------->|
  |<-- ServerHello + key_share + Certificate ----|
  |    + CertificateVerify + Finished            |
  |-- Finished --------------------------------->|
  |<===== 之后全部是 AEAD 加密的应用数据 ========>|

关键点:

  • 密钥交换用 ECDHE 时,双方各生成临时密钥对,交换后算出同一个共享秘密,再经 HKDF 派生会话密钥; 临时密钥用完即弃,因此具备前向安全(forward secrecy)。
  • 证书链验证四件事:域名匹配(SAN)、有效期、能追到受信根、未被吊销(OCSP / CRL)。
  • 应用数据用 AEAD(AES-GCM、ChaCha20-Poly1305)加密,加密的同时校验完整性。

3. 配置与自查

nginx 侧最小可用配置:

server {
    listen 443 ssl;
    http2 on;                # nginx ≥ 1.25.1;更早版本写 listen 443 ssl http2;
    server_name example.com;

    ssl_certificate     /etc/nginx/ssl/fullchain.pem;  # 站点证书 + 中间证书
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 1h;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}

server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

线上排障常用两条命令:

# 看对端实际给出的证书链与协议版本
openssl s_client -connect example.com:443 -servername example.com -tls1_3 -showcerts </dev/null

# 只看叶子证书的主题、签发者与有效期
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates

4. 常见追问

Q:HTTPS 能防什么,防不住什么? 能防窃听、防篡改、防冒充(证书域名不匹配会告警)。 防不住:终端被装了恶意根证书的中间人、服务端自身漏洞、页面里的第三方脚本、流量分析(SNI 与包长仍可见)。

Q:为什么抓包工具能看到 HTTPS 明文? 抓包工具在本机装了自己的根证书,浏览器信任它,它便分别与两端握手,充当中间人。 这是信任链被主动破坏,不是 TLS 被破解。

Q:浏览器正常,App 或 Java 客户端却报证书错误? 多数是服务端只发了叶子证书、没发中间证书。浏览器会用 AIA 自动补链,很多客户端不会。 用 openssl s_client -showcerts 数一下证书条数即可确认。

Q:HTTPS 一定比 HTTP 慢吗? 首次连接多 1~2 个 RTT,之后靠会话复用(session ticket)几乎零成本。 对称加密有 AES-NI 硬件指令,吞吐损失通常在个位数百分比,远小于网络本身的抖动。

Q:全站切 HTTPS 后样式丢了? 混合内容(mixed content):HTTPS 页面里引用了 http:// 的脚本、样式或图片,浏览器会拦截或降级。 改成相对协议或 https,并在 CSP 里加 upgrade-insecure-requests。

小结

HTTP 是"写在明信片上的话",HTTPS 是"装进防拆信封、还验过寄件人身份"的同一句话。 带来安全的不是 HTTPS 这个名字,而是 TLS 的三件套:非对称(ECDHE)协商密钥、对称加密传数据、证书链证明身份。 工程上记住三点:证书要带中间链、80 要跳 443、HSTS 要等全站确认可用后再开。

笔记加载中…