HTTPS

HTTPS

读了工信部近日印发的通知,深感学习网络知识是非常有必要的.. 这篇Blog主要是用于学习HTTPS的基本图像。

我们在浏览器里访问一个网址,本质上是在向这个网址对应的服务器发送一个GET请求,请求服务器发送给我们这个网页对应的HTML文件。或者当我们在Google进行搜索的时候,实际上也是发送一个GET请求,但是这个时候请求中附加了我们的搜索词,服务器解析这个参数,然后返回与之相匹配的结果。所以这个过程大概可以理解为,我们把一个数据包发送给服务器,服务器解析后再返回给我们一个数据包的过程,也就是进行本地和服务器端的网络通信。

上面的过程从结果上看起来只有本地机器和远程服务器两台机器之间进行通信,但实际上数据包的传输会经历很多个中间节点。比如我们发送的数据包,首先会经过我们网线所连接的本地路由器,然后数据包会进入我们的互联网提供商(ISP)的网络,经过他们的交换机和路由器。数据包从我们这个小范围的路由器出去后,可能会经过多个由不同的供应商和提供商控制的高速骨干网络(Backbone Network)。骨干网是用来连接多个区域的高速网络,每个骨干网中至少有一个和其他骨干网进行互联互通的连接点。不同的网络供应商都拥有自己的骨干网,用以连接其位于不同区域的网络。通过骨干网络,我们可以把大范围的区域都连接起来。之后,我们的数据包抵达目标服务器的ISP网络,最后通过目标服务器的本地网络路由器和交换机抵达服务器。

(https://cloud.tencent.com/developer/article/1607505)

于是这个过程就出现了一个问题,假如我们的数据传输协议是明文协议,也就是传输的数据没有经过加密处理,那么在中间任何一个节点的第三方,都可以完整地看到我们和服务器之间所传输的信息。更坏的是,他们还可以随心所欲地劫持我们的流量,不仅包括窥探流量,还可能涉及修改或重定向流量,比如:

  • 内容注入:攻击者可以修改传输的数据,插入恶意广告或恶意代码。
  • 重定向攻击:攻击者可以将用户重定向到仿冒的网站,这些网站看起来可能与原始网站非常相似,但用于窃取凭据或分发恶意软件。
  • 窃取信息:攻击者可以窃取传输中的敏感信息,例如用户名、密码和信用卡信息。

HTTP(超文本传输协议)本身是一种无状态协议,用于在Web服务器和浏览器之间传输信息,它本身不提供任何加密,它是一种明文协议。如何判断数据传输过程中所采用的协议呢?只要查看我们所访问的URL就可以啦,也就是一般聊天时所说的网址。URL的结构通常如下所示:

1
scheme://host:port/path?query#fragment
  • scheme:协议部分,例如 "http"、"https"、"ftp" 等。
  • host:服务器的主机名或IP地址。
  • port:端口号(可选)。
  • path:资源路径。
  • query:查询参数(可选)。
  • fragment:文档内部的定位标识(可选)。

也就是说,当我们所访问的URL是以http://开头的,那么我们所采用的就是HTTP协议,在传输数据时不使用任何加密,这是个非常危险的访问!那么是否有办法在数据传输过程中进行加密,只有本地和服务器才能解读这些数据呢?这其实就是HTTPS协议诞生的原因,也是它所做的事情。HTTPS协议在HTTP的基础上添加了SSL/TLS加密层,相当于在明文传输上面加上了一把锁,通过HTTPS传输的所有数据都经过了加密。当我们访问使用HTTPS的网站时,中间节点没有办法查看我们传递给这个网站的具体内容,尽管他们仍然能看到我们的IP、以及我们正在访问哪个网站。只要服务器端不迫于压力将我们的数据提供给某些部门,我们的隐私就还是得到了基本的保障的。而如果我们使用代理服务器访问某个网站,这时中间节点只能够看到我们和代理服务器之间的连接,而不会看到我们访问了哪个目标网站。

那么HTTPS协议是怎么实现安全连接🔗的呢?我们可以先回顾一下我们采用SSH免密登录服务器的过程。当我们想免密登录一台服务器的时候,我们需要用ssh-keygen生成我们本地机器的公钥和私钥。之后,我们把生成的公钥复制到服务器的.ssh/authorized_keys文件中,私钥保留到自己的机器上。这个时候,当我们用SSH访问服务器的时候,本地机器就会向服务器发送一个请求,请求用本地的密钥进行安全验证。服务器收到请求后,把服务器上储存的公钥和用户发过来的公钥相互比对,如果一致,服务器就会用这个公钥加密“质询”,把它发送给用户机器。用户本地收到“质询”之后,就可用本地的私钥解密再把它发给服务器,即建立连接。所谓的公钥认证,实际上是使用一对加密字符串,公钥用于加密,私钥用于解密;公钥是可见的,私钥是私有的。(P.S. 在数字证书中,私钥还可以用于数字签名,公钥用于验证签名。)

HTTPS本质上也是通过公私钥做加密和身份验证,但是具体的过程和SSH有些不同。HTTPS工作的大致流程是,当用户想向服务器发送数据时,会先向服务器发送一个加密请求,服务器接到加密请求后,把自己的公钥和证书发送给用户。用户验证服务器的证书合法以后,会生成一个会话密钥。用户客户端用会话密钥加密自己要发送的HTTP报文,再用服务器提供的公钥加密会话密钥,把他们一并传输给服务器。这时服务器用自己的私钥解密用户发过来的会话密钥,之后就可以用这个会话密钥解密和加密与用户之间的传递数据了。一旦会话结束,会话密钥即被丢弃,确保即使有人能够窃取密钥,也无法用它解密以前的通信。

上面这个过程涉及到的一个关键内容叫作证书(SSL证书),这个证书部署在服务器上,用户需要验证这个证书是合法的,才能证明收到的服务器公钥是自己想访问的服务器的公钥,而不是盗版病毒网站的公钥。数字证书由称为证书颁发机构(CA)的可信第三方机构颁发。CA负责核实申请证书的组织或个人的身份,并确保公钥确实属于证书申请者。颁发证书后,任何人都可以使用CA所发布的公钥来验证证书上的签名,从而验证证书的真实性。因此服务器如果想采用HTTPS协议,就需要去合法的CA申请一张数字证书,CA在核实了服务器之后,就会给服务器的证书进行签名。一个数字证书包含以下几个内容:

  1. 公钥信息:包括证书拥有者的公钥和加密算法等信息。
  2. 证书拥有者信息:包括组织名称、组织所在地等信息。
  3. 签名算法标识:用于验证证书的算法。
  4. 签名:证书签名,由证书颁发机构(CA)使用其私钥进行签名。

当用户访问一个HTTPS网站的时候,网站返回其数字证书,此时用户的浏览器会使用内置的CA公钥列表验证证书的签名(解密),只有权威的、有资格的CA才会被放置到CA公钥列表中,不合规的小作坊是无法伪造的。如果解密成功,这意味着证书有效可信,此时浏览器和服务器之间就会建立起加密的HTTPS连接。这里要搞清楚几对公私钥,CA的公私钥是用于检验证书是否合法的,服务器的公私钥是用于让用户传过来会话密钥并在服务器上解密的,会话密钥是最终实现HTTP报文加密的。CA的私钥只保留在CA中,而公钥储存在浏览器内置的CA公钥列表中。服务器的公钥保留在用户的客户端和服务器上,私钥只保留在服务器里。会话密钥同时保留在客户端和服务器上,一旦会话结束,会话密钥即被丢弃。这就是HTTPS的大致图像。