HTTPHTTPSTLSDNSRSA
目录
HTTP 协议
HTTPS
TLS 加密过程
TLS握手过程
TLS 第一次握手
TLS 第二次握手
TLS 第三次握手
TLS 第四次握手
DNS
RSA算法
HTTP 协议
超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应,以此为标准可以分为请求报文与响应报文
HTTPS
基础概念
密钥:密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的参数,可以将它理解成现实生活中的钥匙
对称加密:加密解密使用相同密钥,双方在建立连接时商定一个密钥,之后双方使用这个密钥进行加密解密,双方之间传输的是加密后的报文
对称使用一把密钥加密,使用同一把密钥解密。对称加密由于加解和解密使用的是同一个密钥算法,故而在加解密的过程中速度比较快,适合于数据量比较大的加解密
这个方法的缺点在于,双方在建立连接时商定密钥的报文被截取了,任何人都可以冒充目标,所以这个方法不是很安全
非对称加密:这种加密可以生成公钥和私钥,公钥可以用来加密数据,但是不能解密数据。私钥可以用来解密,但是不能用来加密。公钥是公开的,私钥是私有的,私钥一般不会进行网络传输
非对称加密在建立连接时向对方发送公钥,这样就是被截取了,也不能解密数据。这个方法的缺点在于性能,双方都得向对方发送公钥
TLS 加密过程
TLS 协议是基于 TCP 协议之上的,中文名字叫安全传输层协议
图中第一个蓝色往返是 TCP 的握手过程,之后两次橙色的往返,我们可以叫做 TLS 的握手,所以 TLS 一共握手三个来回。握手过程如下:
Client1:TLS 版本号+所支持加密套件列表+希望使用的 TLS 选项
Server1:选择一个客户端的加密套件+自己的公钥+自己的证书+希望使用的 TLS 选项+要求客户端证书
Client2:自己的证书+使用服务器公钥和协商的加密套件加密一个对称秘钥(自己生成的一个随机值)
Server2:使用私钥解密出对称秘钥(随机值)后,发送加密的 Finish 消息,表明完成握手
TLS握手过程
TLS 第一次握手
客户端首先会发一个「Client Hello」消息,字面意思我们也能理解到,这是跟服务器「打招呼」。
消息里面有客户端使用的 TLS 版本号、支持的密码套件列表,支持的压缩算法,以及生成的随机数(*Client Random*),这个随机数会被服务端保留,它是生成对称加密密钥的材料之一。
TLS 第二次握手
当服务端收到客户端的「Client Hello」消息后,会确认 TLS 版本号是否支持,和从密码套件列表中选择一个密码套件,还有选择压缩算法(安全性原因,一般不压缩),以及生成随机数(*Server Random*)。
接着,返回「Server Hello」消息,消息里面有服务器确认的 TLS 版本号,也给出了随机数(Server Random),然后从客户端的密码套件列表选择了一个合适的密码套件。
可以看到,服务端选择的密码套件是 “Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256”。
这个密码套件看起来真让人头晕,好一大串,但是其实它是有固定格式和规范的。基本的形式是「密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法」, 一般 WITH 单词前面有两个单词,第一个单词是约定密钥交换的算法,第二个单词是约定证书的验证算法。比如刚才的密码套件的意思就是:
-
由于 WITH 单词只有一个 RSA,则说明握手时密钥交换算法和签名算法都是使用 RSA;
-
握手后的通信使用 AES 对称算法,密钥长度 128 位,分组模式是 GCM;
-
摘要算法 SHA256 用于消息认证和产生随机数;
就前面这两个客户端和服务端相互「打招呼」的过程,客户端和服务端就已确认了 TLS 版本和使用的密码套件,而且你可能发现客户端和服务端都会各自生成一个随机数,并且还会把随机数传递给对方。
那这个随机数有啥用呢?其实这两个随机数是后续作为生成「会话密钥」的条件,所谓的会话密钥就是数据传输时,所使用的对称加密密钥。
然后,服务端为了证明自己的身份,会发送「Server Certificate」给客户端,这个消息里含有数字证书。
随后,服务端发了「Server Hello Done」消息,目的是告诉客户端,我已经把该给你的东西都给你了,本次打招呼完毕。
TLS 第三次握手
客户端验证完证书后,认为可信则继续往下走。接着,客户端就会生成一个新的随机数 (pre-master),用服务器的 RSA 公钥加密该随机数,通过「Change Cipher Key Exchange」消息传给服务端。
服务端收到后,用 RSA 私钥解密,得到客户端发来的随机数 (pre-master)。
至此,客户端和服务端双方都共享了三个随机数,分别是 Client Random、Server Random、pre-master。
于是,双方根据已经得到的三个随机数,生成会话密钥(Master Secret),它是对称密钥,用于对后续的 HTTP 请求/响应的数据加解密。
生成完会话密钥后,然后客户端发一个「Change Cipher Spec」,告诉服务端开始使用加密方式发送消息。
然后,客户端再发一个「Encrypted Handshake Message(Finishd)」消息,把之前所有发送的数据做个摘要,再用会话密钥(master secret)加密一下,让服务器做个验证,验证加密通信是否可用和之前握手信息是否有被中途篡改过。
可以发现,「Change Cipher Spec」之前传输的 TLS 握手数据都是明文,之后都是对称密钥加密的密文。
TLS 第四次握手
服务器也是同样的操作,发「Change Cipher Spec」和「Encrypted Handshake Message」消息,如果双方都验证加密和解密没问题,那么握手正式完成。
最后,就用「会话密钥」加解密 HTTP 请求和响应了。
DNS
DNS 的作用就是根据域名找到对应的 IP 地址。注意:通过 DNS 解析后,不知道对应端口还是无法访问接口,HTTP 默认使用 80 端口,HTTPS 默认使用 443 端口,因此当用户输入 http://example.com 或 https://example.com 时,浏览器会自动附加默认端口(80 或 443),无需用户显式指定
如果服务监听了非标准端口(如 8080),则需显式声明(如 http://example.com:8080)
如果用户访问的是默认端口(http://example.com,隐式 80 端口),但 Tomcat 运行在 8080,那么请求是如何到达 Tomcat 的呢?
这通常依赖反向代理(如 Nginx/Apache)或端口转发
域名的层级
网址的网址倒过来就是域名的层级关系
然后是根域名,这个 . 就是是根域名,默认情况下所有的网址的最后一位都是.,为了方便用户,通常都会省略,浏览器在请求 DNS 的时候会自动加上
根域名的下一级,叫做顶级域名,或者一级域名
再下一级叫做次级域名,这个域名用户可以自己注册,比如 baodu.com、alibaba.com 等
再再下一级叫做三级域名,这是用户在自己的域里面为服务器分配的名称,是用户可以任意分配的
查找过程
DNS 将域名解析为 IP 地址经历了迭代查找过程,按如下顺序:浏览器缓存、操作系统缓存、本地 DNS 服务器,根 DNS 服务器,顶级 DNS 服务器,主域名 DNS 服务器
1,浏览器缓存:首先,浏览器会检查自己的缓存中是否已经保存了该域名对应的 IP 地址。如果有,则直接使用缓存中的 IP 地址,跳过后续步骤(查询完毕后浏览器一般会保存 DNS 缓存,因此切环境的时候需要清理缓存:edge://net-internals/#dns)
2,操作系统缓存:如果浏览器缓存中没有找到对应的 IP 地址,浏览器会向操作系统发起 DNS 查询请求。操作系统会检查自己的 DNS 缓存,如果有对应的记录,则返回给浏览器(快速切缓存工具:SwitchHosts)
3,本地 DNS 服务器:如果操作系统缓存中没有找到对应的 IP 地址,操作系统会向本地 DNS 服务器发起查询请求。本地 DNS 服务器通常由网络服务提供商(ISP)提供,它负责缓存和转发 DNS 查询请求
4,递归查询:如果本地 DNS 服务器没有缓存对应的 IP 地址,它会向根域名服务器发送查询请求。根域名服务器负责管理顶级域名(如.com、.org、.net 等)的 DNS 服务器地址
5,迭代查询:根域名服务器会返回给本地 DNS 服务器一个顶级域名服务器的地址。本地 DNS 服务器再向顶级域名服务器发送查询请求,获取下一级域名服务器的地址
6,迭代查询继续:本地 DNS 服务器会继续向下一级域名服务器发送查询请求,直到找到负责该域名的权威域名服务器
7,权威域名服务器:权威域名服务器是负责管理特定域名的服务器,它会返回给本地 DNS 服务器该域名对应的 IP 地址
8,返回结果:最后,本地 DNS 服务器将获取到的 IP 地址返回给操作系统,然后操作系统将 IP 地址返回给浏览器
RSA算法
RSA算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)三人一起提出的一种非对称加密算法,RSA的名字由来就是他们三人姓氏开头字母的拼接。如今,RSA在密码传输方面具有比较大的应用,如京东、百度等,在密码传输上使用了这种算法对明文密码进行加密。
RSA算法的基础操作步骤
1.生成公钥和私钥
生成公钥PK和私钥SK的步骤如下:
(1)随意选择两个大的素数P、Q,P不等于Q。
(2)将P、Q两个素数相乘得到一个N,即N=P*Q
(3)将P、Q分别减一,再相乘,得到一个数T,即T=(Q-1)*(P-1)
(4)选择一个整数E,作为一个密钥,使E与T互质(即E与T的最大公约数为1),且E必须小于T。
(5)根据公式D*E mod T = 1 ,计算出D的值,作为另一个密钥。
(6)通过以上的步骤就可以求出N,E,D这三个数据,其中(N,E)作为公钥,(N,D)作为私钥。
2.用公钥加密信息
发送信息的一方收到公钥PK后,就可以通过公钥PK对数据进行加密,加密的操作步骤如下图所示,其中明文为:M,密文为:C
明文:M
加密:
密文 :C
3.用私钥解密信息
接收方持有私钥(N,D)在接受到密文C后,既可以通过私钥解密,得到明文M,解密过程如下:
密文:C
解密:
明文:M
RSA 算法的缺陷
使用 RSA 密钥协商算法的最大问题是不支持前向保密。因为客户端传递随机数(用于生成对称加密密钥的条件之一)给服务端时使用的是公钥加密的,服务端收到后,会用私钥解密得到随机数。所以一旦服务端的私钥泄漏了,过去被第三方截获的所有 TLS 通讯密文都会被破解。
为了解决这一问题,于是就有了 DH 密钥协商算法,这里简单介绍它的工作流程。
客户端和服务端各自会生成随机数,并以此作为私钥,然后根据公开的 DH 计算公示算出各自的公钥,通过 TLS 握手双方交换各自的公钥,这样双方都有自己的私钥和对方的公钥,然后双方根据各自持有的材料算出一个随机数,这个随机数的值双方都是一样的,这就可以作为后续对称加密时使用的密钥。
DH 密钥交换过程中,即使第三方截获了 TLS 握手阶段传递的公钥,在不知道的私钥的情况下,也是无法计算出密钥的,而且每一次对称加密密钥都是实时生成的,实现前向保密。
但因为 DH 算法的计算效率问题,后面出现了 ECDHE 密钥协商算法,我们现在大多数网站使用的正是 ECDHE 密钥协商算法。