3、HTTP与HTTPS:从明文到加密的蜕变

说实话,我刚入行那会儿,对HTTPS的理解也就停留在「比HTTP安全」这个层面。直到有一次,我在一个咖啡厅做渗透测试,用Wireshark抓了个包——好家伙,隔壁桌小哥的登录密码、银行卡号,全在HTTP请求里躺着呢。那一刻我才真正意识到,HTTP就是裸奔,HTTPS才是穿了防弹衣。

这一章,咱们就把HTTPS的加密过程、HSTS策略、中间人攻击和证书固定这几个核心话题聊透。你想想看,每天几十亿次HTTPS握手,背后到底发生了什么?

3.1 HTTPS加密过程:一次完整的握手

HTTPS的核心,说白了就是HTTP + TLS(传输层安全协议)。TLS负责加密,HTTP负责传输。我习惯把TLS握手分成四个阶段来讲:

  1. TCP三次握手:客户端和服务器先建立TCP连接。
  2. 证书验证:服务器把数字证书发给客户端,客户端验证证书的合法性。
  3. 密钥交换:双方协商出一个对称加密密钥,用于后续数据传输。
  4. 加密通信:用协商好的密钥加密HTTP数据。

嗯,这里要注意,TLS 1.3相比1.2,把握手从2-RTT优化到了1-RTT,甚至0-RTT。我去年帮一家电商平台做性能优化,光是把TLS 1.2升级到1.3,首屏加载时间就降了30%。

核心要点:HTTPS不是「HTTP + SSL」这么简单。它涉及证书链验证、非对称加密交换密钥、对称加密传输数据,每一步都有安全考量。

咱们用一张图来理解整个流程:

HTTPS TLS 1.3 握手流程 HTTPS TLS 1.3 握手流程 客户端 (Client) 服务器 (Server) ① TCP三次握手 ② ClientHello ③ ServerHello + 证书 ④ 验证证书 + 发送密钥 ⑤ 确认 + 加密通信 TLS 1.3 将握手从 2-RTT 优化到 1-RTT,0-RTT 模式可复用之前会话

3.2 数字证书与CA体系

你可能会问:客户端怎么知道服务器发来的证书是真的?这就涉及到CA(证书颁发机构)体系了。

我个人的理解是,CA就像数字世界的「公安局」。它给网站颁发身份证(证书),浏览器里预装了「公安局」的公钥。当服务器出示证书时,浏览器用CA的公钥验证签名,确认证书没被篡改。

证书类型 验证级别 适用场景 价格参考
DV(域名验证) 低 个人博客、小型网站 免费 ~ 几百元/年
OV(组织验证) 中 企业官网、电商平台 千元级/年
EV(扩展验证) 高 银行、金融、政府网站 数千元/年

我的建议:个人项目用Let's Encrypt免费证书就够了。企业项目至少用OV证书,EV证书虽然贵,但浏览器地址栏会显示公司名称,用户信任度更高。

3.3 HSTS策略:强制HTTPS的「铁腕手段」

HSTS(HTTP Strict Transport Security)是个好东西。它告诉浏览器:这个网站只能用HTTPS访问,别给我走HTTP。

我曾经遇到过一个案例:某银行网站虽然支持HTTPS,但用户输入网址时习惯打 http://,服务器会302重定向到HTTPS。这中间就有一次明文请求,中间人完全可以劫持这次重定向,把用户引到钓鱼网站。

HSTS的配置很简单,在服务器响应头里加一行:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

参数说明:

  • max-age:告诉浏览器记住这个策略的时间(秒)。31536000秒就是1年。
  • includeSubDomains:子域名也强制HTTPS。
  • preload:申请加入浏览器内置的HSTS预加载列表。

注意:设置HSTS要谨慎。一旦浏览器记住了,在max-age过期前,你没法通过HTTP访问自己的网站。我曾经见过有人把max-age设成10年,结果证书过期了,网站直接瘫痪——因为浏览器拒绝HTTP连接,而HTTPS证书又无效。

3.4 中间人攻击:HTTPS最大的威胁

中间人攻击(MITM),说白了就是攻击者站在你和服务器之间,冒充你和服务器通信。HTTPS能防住普通的MITM,但有一种情况防不住——客户端没有验证证书。

常见的MITM手法:

  1. 伪造证书:攻击者用自己的证书替换服务器证书。如果用户点了「继续访问」,那就中招了。
  2. ARP欺骗:在局域网内伪造网关MAC地址,让流量经过攻击者机器。
  3. DNS劫持:把域名解析到攻击者的服务器。
  4. SSL剥离:把HTTPS降级成HTTP,用户完全不知情。

我记得有一次帮客户做安全审计,发现他们的移动App没有做证书固定。我在同一WiFi下用Fiddler抓包,直接就能看到所有HTTPS请求的明文内容——因为App信任了Fiddler的根证书。这就是典型的MITM场景。

3.5 证书固定:给HTTPS加把「指纹锁」

证书固定(Certificate Pinning)是解决MITM的终极方案。它让客户端只信任特定的证书或公钥,而不是信任所有CA签发的证书。

实现方式有两种:

方式 原理 优点 缺点
硬编码证书 把服务器证书的SHA-256指纹写死在代码里 最安全,无法绕过 证书更新时需要发版
公钥固定 固定证书的公钥,而非整个证书 证书更新但公钥不变时无需发版 实现稍复杂

以Android为例,用OkHttp实现证书固定:

CertificatePinner certificatePinner = new CertificatePinner.Builder()
    .add("example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
    .build();

OkHttpClient client = new OkHttpClient.Builder()
    .certificatePinner(certificatePinner)
    .build();

避坑指南:我曾经在项目中把证书指纹写死,结果证书过期后App全部崩溃。后来我改用公钥固定,并预留了备用公钥。这样主证书过期时,用备用证书顶上,App不用发版。

3.6 总结:HTTPS防护的「三层防线」

聊了这么多,我习惯把HTTPS防护总结成三层:

  • 第一层:TLS加密——防窃听、防篡改。这是基础,但不够。
  • 第二层:HSTS——防SSL剥离、防降级攻击。强制使用HTTPS。
  • 第三层:证书固定——防伪造证书、防MITM。给信任加上「指纹锁」。

你想想看,这三层都做好了,攻击者想搞你,难度就大多了。当然,没有绝对的安全,但至少咱们不能让攻击者「捡漏」。

嗯,这一章就到这里。记住:HTTPS不是配置完就完事了,证书要续期、HSTS要规划、证书固定要留后路。安全是个持续的过程,不是一锤子买卖。