Skip to content
导航

HTTPS

HTTPS(HyperText Transfer Protocol Secure,超文本传输安全协议)是 HTTP 协议的加密版本。
它使用 TLS(Transport Layer Security,传输层安全性)协议来加密客户端和服务器之间所有的通信。

TLS协议

此协议通过使用知名的非对称公钥基础结构来保护通信。
这种类型的安全系统使用两个不同的密钥来加密双方之间的通信:

  • 私钥
    此密钥由网站所有者控制,它是私有的。此密钥位于 Web 服务器上,用于解密通过公钥加密的信息。
  • 公钥
    所有想要以安全方式与服务器交互的人都可以使用此密钥。用公钥加密的信息只能用私钥解密。

数字证书、CA、根证书

由于公钥是公开的,任何人都可以获取,因此为保证公钥和网站的真实有效,有了数字证书数字证书颁发机构 (CA)
相当于有了公证处公证,这个公钥真的是这个网站的。

但是,数字证书、数字证书颁发机构都可以是不安全的:

  • 抓包工具会要求你把自签名数字证书安装到客户端的受信任证书颁发机构(CA)中,就可以充当Web服务器代理HTTPS流量。
  • 使用公司WiFi可能要求你安装根证书,是最高级别证书,可以充当证书颁发机构验证其他证书的有效性。也就可以结合网络通讯设备实现同上方式代理HTTPS流量。

HSTS

HTTP Strict-Transport-Security(通常简称为 HSTS)响应标头用来通知浏览器应该只通过 HTTPS 访问该站点,并且以后使用 HTTP 访问该站点的所有尝试都应自动重定向到 HTTPS。

HTTP是不安全的,可能已经被攻击过了。HSTS标头在通过HTTP访问时会被浏览器忽略。
因此HSTS标头不能实现HTTP升级HTTPS协议,Web服务端仍然要处理HTTP重定向到HTTPS协议。

Chrome 90 起,浏览器将会默认使用HTTPS协议打开URL

headers语法

Strict-Transport-Security: max-age=<expire-time>
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains; preload
  • max-age=<expire-time>:指定浏览器应该记住只能使用HTTPS访问该网站的最大时间,单位:秒。
  • includeSubDomains:子域名也适用此规则。
  • preload:非标准。控制浏览器使用浏览器厂商维护的HSTS列表。

HTTP 与 HTTPS 混合使用的问题 【补充】

鉴于HTTPS有额外的证书配置、加解密性能损耗,内网开发时一般仍然会使用HTTP。

因此HTTPS不会取代HTTP,两者会持续共存。通常它们井水不犯河水,但特殊场景下会出现需要建立联系的情况,例如 iframe 嵌套网页,又或者不同协议的网页请求接口。

HTTPS 混入 HTTP

iframe 会被浏览器拦截,报错如下:

Mixed Content: The page at 'https://test.com/' was loaded over HTTPS, but requested an insecure frame 'http://test.com/'. This request has been blocked; the content must be served over HTTPS.

XHR 同样被拦截,报错同上,frame 替换为 XMLHttpRequest endpoint

<img> 加载http图片也被拦截,报错近似,但会自动更换到https协议后重新请求:

Mixed Content: The page at 'https://test.com/' was loaded over HTTPS, but requested an insecure element 'http://test.com/img.jpg'. This request was automatically upgraded to HTTPS, For more information see https://blog.chromium.org/2019/10/no-more-mixed-messages-about-https.html

小结:HTTPS 混入 HTTP 会报错 Mixed Content,请求被浏览器拦截,资源被浏览器拦截或重定向。

HTTP 混入 HTTPS

iframe 成功加载,但是frame内访问 document.cookie 为空。

XHR 简单请求、复杂请求均成功。但是设置 XHR.withCredentials = true 后:

  • 简单请求带上了 cookie (并且尽管源不同,相同 domain、path 不同协议、端口的 cookie 相互覆盖)
  • 复杂请求没有带上 cookie,浏览器不报错。同样的请求换 http 协议后成功带上 cookie

<img> 成功。

但是,HTTP 混入 HTTPS,对于HTTPS来说是不安全的,因为HTTP可能被攻击过了。

参考资料