域名
组成部分
-
顶级域名:最右侧的部分,表示域名的类型、地区
通用顶级域(gTLD):.com、.org、.net、.edu 地区顶级域:.cn、.us、.jp 新通用顶级域:.ai、.blog、.app
-
二级域名:紧邻顶级域名的左侧部分
用户可注册的核心域名,通常由域名注册商(GoDaddy、spaceship等)提供
-
子域名:二级域名的左侧部分,可多层嵌套
由域名所有者自行配置 www.lvyourz.com、mail.lvyourz.com、api.lvyourz.com,www、mail、api是子域名
统一资源定位符(URL)有时也称为网址,包含站点的域名以及其他信息,例如传输协议和路径等。例如,在"https://lvyourz.com/posts/“这个URL中,“lvyourz.com"是域名,“https"是传输协议,”/posts/是指向网页上特定页面的路径
-
A:将域名指向一个IPv4地址
可直接用于根域名(lvyourz.com)或子域名(www.lvyourz.com)
例:lvyourz.com A 99.171.200.6
-
AAAA:将域名指向一个IPv6地址
例:lvyourz.com AAAA 2606:2800:220:1:248:1893:25c8:1946
-
CNAME:将域名指向另一个域名,而不是直接指向一个IP地址
不能用于根域名(lvyourz.com),可用于子域名(www.lvyourz.com) 会增加一次DNS记录
例:www.lvyourz.com CNAME lvyourz.com,访问www.lvyourz.com时,DNS会先查询lvyourz.com的A/AAAA记录,再返回IP
DNS
域名服务器采用“分布式数据库”的形式,根据域名段来进行划分,找不到的记录就交给下层服务器查询,这种只与根服务器对接的方式叫做递归查询
为了提高域名IP查询的速度,运营商通常会建立代理服务器,代理服务器通过缓存机制,缩短响应时间 代理服务器可以使用迭代查询的模式,甚至直接找到末端服务器查询,减少了根服务器的压力,迭代查询也是主要的域名IP查询方式
特征 | 递归查询 | 迭代查询 |
---|---|---|
责任方 | 接收请求的服务器完成所有查询 | 请求方自行逐步查询 |
响应内容 | 最终答案(或错误) | 可能返回下一级服务器的参考信息 |
典型场景 | 客户端 ↔ 本地DNS服务器 | DNS服务器之间的交互 |
性能影响 | 递归服务器负载高 | 查询方需多次请求 |
本地服务器、根服务器、顶级域名服务器、权威域名服务器共同组成了DNS服务
浏览器、计算器缓存会将域名IP缓存起来,并非每次都需要进行DNS查询。有了IP就可以使用TCP协议进行通信,网页的每次请求都会经理建立连接、断开连接的过程
https
发送请求的内容约定好格式:请求方式、路径、域名等,服务器也按照一定的格式响应消息,这个双方约定的格式就是http协议
计算机发送的消息会经过若干个路由器的转发,此时发送的消息是明文的,任何人都可以对内容进行查看、篡改,需要对内容进行加密处理
TLS CipherSuite主要由密钥交换方法、身份验证方法、密码定义(包括对称加密算法、安全强度、认证与分组模式)以及可选的MAC或PRF算法组合而成(如果未采用 AEAD 认证加密方案,则需提供 MAC;若采用 AEAD,则无需单独指定 MAC)
假设加密是一把锁,将钥匙看作是加密的密钥,客户端需要密钥发给服务器,然后使用这把密钥对内容进行加密,之后把密文发送给服务器,服务器使用相同的密钥就可以解密内容了,这种加密、解密都是用同一把密钥的加密方式叫做对称加密,例如加减法就是一个最简单的对称加密,常见的对称加密算法有AES
、DES
等
对称加密需要先将密钥发送出去,这时攻击者可以从中间拦截,然后自己配一把密钥,之后的密文都能解开了,这个加密流程就形同虚设了
于是我们需要一种复杂的锁,这个锁有两个不同的钥匙孔,以及对应的两个不同的钥匙,一把是公钥,一把是私钥,使用公钥上锁,只能用私钥解锁,使用私钥上锁,只能用公钥解锁,这个就是非对称加密,最常用的非对称加密算法有RSA
等
有了非对称加密,服务端就可以把公钥传递出去,攻击者可以偷配公钥,客户端使用公钥对内容加密后,将密文发送给服务端,攻击者没有私钥,不能解密内容,服务端使用私钥来进行解密。
攻击者虽然没有服务端的私钥,但是却可以将自己的公钥替换成服务端的公钥给客户端,客户端收到后,以为这是服务端的公钥,进行加密后发送给服务端,攻击者就可以使用自己私钥来解密内容,之后为了潜伏,再使用服务端的公钥进行加密发送给服务端,进而达到长期监听的目的,这就是所谓的中间人攻击。
CA:受信任的第三方机构,负责验证网站或实体的身份,并为其颁发证书
签名:CA机构不是直接使用它的私钥机密服务端发送的全部信息,CA机构会计算服务端提交的信息(域名、公钥等)的哈希值,CA机构用自己的私钥对这个哈希值进行加密,这个加密后的哈希值就是数字签名。
证书:一个数字文件,由CA机构颁发,绑定了一个公钥和该公钥所属实体的身份信息。包含公钥信息、拥有者身份信息、颁发证书的CA机构名称、证书有效期以及CA机构对上述信息的签名。
签名而非直接加密信息:
- 证书中的域名、公钥等信息需要是明文的,以便客户端读取使用
- 对哈希值加密比直接加密所有内容更快
- 对证书内容的篡改会被发现
证书产生流程:申请 => 审核 => 签名 => 颁发
首先服务端会把自己的域名、公钥等信息发给CA机构,CA机构审核后,会将这些信息用非对称加密加密起来,加密后的内容变成了证书,之后“肉身”送给了服务端,再把CA公钥运送给客户端(客户端会预先信任一些知名的、行为规范的的CA机构(根CA)),方便客户端解密证书。之后客户端要和服务端进行通信,需要先将证书发送给客户端,客户端这时有CA的公钥,如果可以解密证书,证明证书没有被篡改过,如果攻击者伪造了证书,客户端就无法解密证书,这样就解决了公钥身份问题。“肉身”运送是指通过电话、邮件等多种信道来降低中间人攻击的风险,客户端CA机构的公钥通常是浏览器或计算机出产自带的。
解密证书,证明证书没有被篡改过流程:
- 客户端使用本地存储的该CA机构的公钥,去解密证书中的数字签名,得到哈希值X,客户端自己计算证书中的明文部分得到Y。比较X和Y。
- X == Y:证书内容自CA签名后没有被篡改;证书确认是该CA机构签发的
- X != Y:证书无效,可能被篡改或伪造
有了CA机构后,可以解决中间人攻击的问题,但是非对称加密相比对称加密耗费计算资源更大,加密后的密文更长,通常不会直接使用非对称机密来通信,而是用来传递对称加密的密钥,客户端把对称加密密钥拿出来,用非对称所加密,之后服务端用私钥解密,得到对称机密的密钥,之后就使用对称加密来通信。
HTTPS握手过程中的验证流程(简化RSA密钥交换):
- 客户端发起连接:访问
https://www.lvyourz.com/
- 服务端发送证书(服务端将证书发送给浏览器)
- 客户端验证证书:
- 证书链验证:验证证书是否由它信任的根CA签发(或由根CA的信任的中间CA签发)
- 签名验证
- 域名验证:检查证书中的域名是否与实际访问的域名一致
- 有效期验证:检查证书是否在有效期内
- 密钥交换:如果所有验证通过,从证书中获取到服务端的公钥
- 客户端生成一个对称会话密钥
- 客户端用服务器的公钥加密对称密钥,发送给服务端
- 服务端使用私钥解密获得会话密钥
- 双方拥有相同的对称密钥
- 安全通信:后续通信都是用这个会话密钥来进行对称加密和解密
密钥交换算法使得通信双方可以在非安全信道中安全地交换用于加密后续通信消息的密钥,常用的密钥交换算法包括:RSA
、DH
、DHE
、ECDH
、ECDHE
,许多密钥交换算法(如Diffie-Hellman)基于非对称加密相同的数学原理。
DH密钥交换
DH(Diffie-Hellman)密钥交换基于单向函数取模运算。
- Alice 和 Bob 约定使用 G^x^ MOD P,他们公开选定两个大数:一个质数
P
(例如P = 101
) ,一个质数G
(例如G = 7
) - Alice、Bob分别选择一个数A、B,分别将自己选择的数带入函数 G^x^ MOD P,得到α、β
- 两人将计算结果告诉对方。如果有人监听到通信信道上的
P
,G
,α
,β
。由于计算 G^X^ MOD P的过程(模幂运算)在已知G
,P
, 结果 (α
或β
) 的情况下,逆运算(求解离散对数X
)在计算上是不可行的(对于足够大的P
),因此无法从α
推导出私钥A
,也无法从β
推导出私钥B
。 - Alice 和 Bob 得到对方的结果后,Alice 使用私钥执行运算 β^A^ MOD P(即 G^A·B^ MOD P),Bob使用私钥执行运算 α^B^ MOD P(即 G^A·B^ MOD P)
- 他们将得到完全相同的结果,即会话密钥
在上述过程中,G、P 被称为域参数,通常由服务器选择域参数,发送给客户端,以约定初始条件。DH 密钥交换的安全性在很大程度上取决于这两个域参数的质量。
完全前向保密
在DH密钥交换过程中,服务端的公钥以及私钥都是固定的,只有客户端的公私钥是随机生成的,因此不具备完全前向保密能力(密钥泄露也不能使用密钥解密之前的的密文),想要完全前向保密能力,需要每次交换的公钥都是不同的,需要在每次选择时都是用临时私钥,具备这种特性的DH称为DHE(Diffe-Hellman Ephemeral)。DHE是TLS 1.2/1.3支持的密钥交换方案
ECDH密钥交换
ECDH(Elliptic Curve Diffie-Hellman Key Exchange) 的安全性基于椭圆曲线密码学(ECC)的核心特性:
- 给定椭圆曲线上一个公开点 P 和整数 k,计算 Q=k⋅P(标量乘法)是高效的;
- 但若已知 Q 和 P,反推 k 在计算上不可行(椭圆曲线离散对数问题,ECDLP)。
在 ECDH 密钥交换流程中,服务端使用证书中的公钥,因此必须采用 ECC 证书,ECDH 不具备完全前向保密能力。
ECDHE密钥交换
服务端生成临时椭圆曲线密钥对:(server_ephemeral_priv, ServerPub)
,使用长期身份私钥对 ServerPub
签名,发送 ServerPub
及签名至客户端。
客户端生成临时椭圆曲线密钥对:(client_ephemeral_priv, ClientPub)
,发送 ClientPub
至服务端(通常无需签名)。
临时私钥 server_ephemeral_priv
/ client_ephemeral_priv
仅在本次会话使用,服务端的长期身份私钥独立存储,不参与密钥协商
RSA密钥交换
如果获得服务端的私钥,那么就可以获得 Pre-Master,进而生成会话密钥,所以 RSA 不具备完全前向保密能力。
TLS 1.2握手流程(ECDHE)
- 包括密码套件列表以及客户端随机数
- 密码套件及其服务器随机数
- 服务器的公钥证书(被CA签名过的)
- 服务器获取用以计算会话密钥的DH参数(Server Paradms),并使用服务器私钥进行签名,发送给客户端,客户端使用公钥来验证签名,
- 协商结束
- 客户端获取用以计算会话密钥的DH参数(Client Paradms),发送给服务器(客户端和服务器都拥有了ECDHE算法需要的2个参数:Server Params、Client Params, 客户端、服务器都可以使用ECDHE算法根据Server Params、Client Params计算出一个新的随机预密钥: Pre-master secret, 结合Client Random、Server Random、Pre-master secret生成一个主密钥, 最后利用主密钥衍生出客户端会话密钥用于客户端发送消息以及服务器对该消息进行解密; 服务端会话密钥用于服务器发送消息,以及客户端对该消息进行解密)
- 客户端发送 “Change Cipher Spec” 消息,通知另一方它切换到加密。
- 客户端发送最终的 “Finished” 消息,以指示它已完成其握手部分。
- 同样,服务器会发送 “Change Cipher Spec” 消息。
TLS 1.3
tls1.2流程太繁琐了,tls1.3中将所有的随机数、加密材料合并发送,tls1.3中一个来回就完成了安全通信建立
http1.0
中一个请求需要建立一个TCP
连接,然后发送、等待响应,如果由多个请求,就建立多个TCP
连接,连接建立和断开都需要多次握手,这回造成资源的浪费。http1.1
中,加入了连接保持(Keepalive)机制,请求完成后,不会立刻关闭连接,下一个请求会使用这条连接,这样后面的请求要等待上一个请求完成后才能发出,如果一个网页资源过多,就会等待很长时间,http1.1
中加入了管线化(Pipelining)机制,允许多个请求一起发出,无需等待上一个请求响应,但是如果前面的请求数据量大、或丢失,会阻塞后面的请求。在http2
时,将单个请求数据做了拆分,拆成若干个小块,对方接受后再按顺序重组,避免了数据量大阻塞后面的数据,虽然总传输时间不变,但是拆分后可以时小请求更快完成加载,体验更好。http2
不是简单的拆分,是把数据分成头部帧和数据表,多个网页请求,头部往往是高度一致的,于是通过建立头部索引表,可以大大减少头部数据量,这就是HPACK头部压缩。http1
、http2
都是基于TCP协议的,由于TCP排序机制,使得http无法摆脱头部阻塞的问题,于是http3
中不再基于TCP而是基于UDP,并实现了一套连接协议QUIC
,UDP是无序的,没有对头阻塞的问题,如果某个流发生了阻塞,不会影响其他流,在http3
之前需要建立连接后才能建立tls握手,tls1.3
减少了握手次数,http3
将建立连接的过程和tls握手的过程融合在一起,一个来回就完成了建立连接和tls握手,使得http3
非常迅速。