传输层安全协议(TLS)和它的前任——安全套接字层协议(TLS)——现在已经被 IETF 禁止使用,是一种提供基于计算机网络通信安全的密码学协议。
流程
在建立一个 TCP 连接后,由客户端开始 TLS 握手。客户端发送一些规格说明给服务器:
- 运行的 TLS 版本
- 想使用哪些加密套件
- 想使用哪些压缩算法
服务器检查两者所能支持的最高 TLS 版本,从客户端提供的加密套件中选择一个它支持的,并且随机的选择一个压缩方法。
- 服务器发送它的证书。这个证书必须被客户端信任或被客户端信任的证书机构签名。
判断证书是否可信
比如当谷歌服务器将它的证书发送给你的时候,它也会提及它是由 GeoTruest 签名的。如果你信任 GeoTruest,你可以根据 GeoTruest 的公钥来验证证书上的签名,如果验证成功,说明这个证书是可信的。
如果你想自己签名一个证书,你需要 GeoTruest 的私钥。所以攻击者不能以这种方式签名一个证书并且谎称它是 Google.com。
判断服务器是否可信
由于证书是公开的,所以我们还要验证服务器是否可信。
客户端使用证书上的公钥加密一个信息并发送给服务器,如果服务器能返回相同的信息,就证明它有对应的私钥,而不需要暴露这个私钥。
对称加密
客户端以公钥加密对称加密的密钥(以下简称密钥)发送给服务器。服务器可以使用私钥解密出密钥,而攻击者不可以。
客户端告诉服务器,从现在之后,所有的通信将会使用密钥加密,并且发送一个加密的验证信息给服务器。
服务器验证信息验证码是正确的,并且信息可以被正确的解密。服务器返回一个新的加密的验证信息,客户端也进行同样的校验。
现在握手结束了,两个主机可以安全的通信了。
信息验证码(Message Authentication Code)
在密码学中,信息验证码是一小片用来验证信息的信息。为了确保信息来自于正确的发送者,并且没有被修改过。
协议的输入是信息和密钥,输出是信息验证码。如果攻击者修改信息,但是由于它不知道密钥,所以信息验证码会对不上。
证书机构
一个网站想要和你安全的交流。为了证明它的身份,并确保它不是一个攻击者,你必须拥有服务器的公钥。然而,你不可能储存地球上所有网站的公钥,对应的数据库会很大并且需要定期更新。
解决的办法是证书机构(Certificate Authorities)。当你安装你的操作系统或者浏览器时,可能会带有一个信任的证书机构列表。你可以修改这个列表:删除你不信任的,增加你信任的。在这个证书机构列表中也储存了证书机构的公钥。
信任证书机构
证书机构可以使信任它的客户端,信任任何服务器。这是信任的来源。当类似微软、苹果和 Mozilla 等组织信任一个证书机构时,这个证书机构必须被监管。另一个组织定期检查它们,以确保所有事都按规则进行。
只有当注册者能证明它们拥有证书对应的域名时,证书才会被发放。
如何攻破 TLS
- 如果用户忽略证书警告
- 应用从非加密渠道加载数据(比如 HTTP),可能造成数据泄露
- 一个不受保护的提交到 HTTPS 的登录页,可能被修改为提交到 HTTP
- 使用其它手段,比如物理攻击。
所以,只有当正确使用 TLS 的时候,TLS 才是安全的。
当一个用户忽略证书的安全警报,将会立刻破坏安全性。攻击者不需要证书对应的私钥来伪造证书,它只需要发送一个它自己的证书。
如果网站从 HTTP 加载资源(比如图片或者脚本),那么机密性不再得到保障。攻击者可以通过你访问的图片,来判断你访问的网站是什么。另外当加载 javascript,整个页面都会被危及。攻击者可以在该页面上执行任何脚本。比如更改你的银行转账目标。当发现网站从 HTTP 加载资源的时候,浏览器会给出警告。
在过去几年还有多种攻击方式。但是所有的主流浏览器都可以免受其攻击。所以你应该运行最新版本的浏览器。
Requests TLS 安全性
Requests 会验证 HTTPS 请求的 TLS 证书,就像浏览器一样。如果验证失败,会抛出一个异常。
Request 使用 certifi
包中的证书。这使得用户可以更新它们的信任证书,而不需要更改 Requests 的版本。
在 2.16 版本之前,Requests 打包了一些来自 Mozilla trust store 的它信任的根证书。只有当 Requests 版本更新的时候,这些证书机构才会被更新。当没有安装 certifi
并且使用更早(小于 2.16)版本的 Requests 时,会导致证书严重过期。
为了安全推荐频繁更新 certifi
。