正常简单的通讯
1、服务器生成一对密钥,公钥A、私钥A
2、浏览器请求服务器时,服务器把公钥A传给浏览器
3、浏览器随机生成一个对称加密的密码S,用公钥A加密后传给服务器
4、服务器接收后,用私钥A解密,得到密钥S
5、浏览器和服务器都知道密钥S,就可以使用密钥S加密数据然后传输
这样看起来可以通讯,但是是有漏洞的。
中间人攻击
1、服务器生成一对密钥,公钥A、私钥A。
2、浏览器请求服务器时,服务器准备把公钥A传给浏览器;此时中间人X,生成也生成一对密钥,公钥B、私钥B,X劫持到公钥A后替换成自己的公钥B,发给浏览器。
3、浏览器无法分辨公钥B是否是服务器的,生成一个对称加密密钥S,公钥B加密后准备传给服务器,其实传给了中间人X。
4、中间人收到后,使用私钥B解密拿到密钥S,然后再使用公钥A加密传给服务器
5、服务器收到后使用私钥A解密也拿到密钥S。
6、浏览器和服务器使用密钥S加密后传输数据,此时中间人X也是持有密钥S,劫持到数据包后使用密钥S就能解密。
这种情况,服务器和客户端都不会发现异常,因为客户端无法确认收到的公钥是不是服务器的。因为公钥是明文形式传播的。如何证明公钥是服务器的,就出现CA机构?
CA机构
CA机构相当于现实中的“派出所”,数字证书就相当于“身份证”。
数字证书
网站在使用HTTPS之前,需要向CA机构申领一份数字证书,数字证书包含服务器的信息(包含版本号、序列号、签名算法、颁发者、网站服务器公钥(RSA签名公钥)等信息)
数字签名
**证书会被修改吗?**证书中会包含一段私钥加密的签名,是将证书的内容进行HASH得出。如果证书被篡改,签名会对不上。这个签名就是数字签名,用来防伪的技术。
证书生成
a、CA机构有非对称加密的私钥和公钥,(私钥保存在CA服务器上,公钥(其实是CA机构证书链上的根证书的公钥)预装在各个操作系统、电脑上、Android等)
b、CA机构对证书数据X进行HASH(证书数据包括版本号、序列号、HASH签名算法、颁发者、服务器的公钥等)
c、用CA的私钥对HASH值H进行加密,得到数字签名S,并添加到证书上就是数字证书。
证书验证
a、浏览器拿到证书后,通过证书链验证颁发者是否可信,然后得到数据T,以及签名S
b、用预装的CA机构证书链上的根证书的公钥对S进行解密,得到H
c、使用证书里的HASH签名算法,对数据T进行HASH得到H1,此时H1应该等于H,说明未被篡改
质疑思考
a、**证书会被掉包吗?**证书里包含了网站的信息(包括域名等),证书如果被替换,浏览器能知道访问的网站和证书是否一致
b、**为什么数字签名要HASH一次?**证书信息一般比较长(**为什么不能只用非对称加密?**非对称加密算法可以加密的数据长度有上限,否则会报错或者需要分割加密效率极低),使用HASH算法得到证书信息的摘要,将数据变短能提高加密和传输的效率,也能更安全
c、怎么确保CA的公钥时可信的?各个操作系统、电脑上、Android设备上会预装一些CA机构的根证书,根证书中包含公钥,验证的时候通过证书链,以根证书为起点,层层信任。
d、**TLS每次都会传递密钥吗?**服务器会给每个客户端维护一个Session ID,将密钥存到对应的Session ID下,客户端请求的是时候携带Session ID(表示恢复之前的会话,如果Session ID为空时,表示不用恢复客户端和服务器重新协商密钥),服务器就会使用对应的密钥进行加密,不需要重新协商密钥。
TLS协议
TLS协议的作用
1、认证用户和服务器,确保数据发送到正确的客户机和服务器;
2、加密数据以防止数据中途被窃取;
3、维护数据的完整性,确保数据在传输过程中不被改变。
分为两层:记录层和握手层
上层-握手层包含4个协议
**握手协议 **进行身份认证、协商共享密钥
**更改密码规范协议 **根据握手协议协商的结果,切换加密密码套件
**应用数据协议 **通信双发进行数据传输的协议
**警告协议 **当以上过程发生错误时通知对方
下层-记录层
记录层协议
**添加消息头 **给数据添加消息头后封装交给TCP层
**分片重组 **发送方将数据分割成小的数据块,接收方可以将小数据块重组
**数据压缩解压缩 **对数据进行压缩和解压缩
**加密解密 **对数据进行加解密和解密
完整的握手过程
第一次握手:客户端发送
Client Hello 客户端Hello包
**Version **客户端支持的最高版本号
**Random **客户端随机数,每次握手都会重新生成(可以防止重放攻击),用于后续生成密钥
**Session ID **会话ID用于恢复会话,第一次是空表示不恢复会话,在后续的连接中,服务器可以借
助会话ID在自己的缓存中找到对应的会状态,这样只需1RTT既可以完成握手,完整
的握手协议2RTT(2次网络往返)才能完成握手
**Cipher Suites **客户端支持的所有密码套件,按优先级排列
**Compression Methods **压缩方法
**Extension **扩展数据
16进制数据分析
# 16 03 03 00 be 01 00 00 ba 03 03 64 c4 d9 0a 37 40 a3 af d6 27 66 d1 bb 29 d0 53 c8 e0 dc 14 16 06 cf d1 1a 40 eb c0 d3 67 48 57 00 00 26 c0 2c c0 2b c0 30 c0 2f c0 24 c0 23 c0 28 c0 27 c0 0a c0 09 c0 14 c0 13 00 9d 00 9c 00 3d 00 3c 00 35 00 2f 00 0a 01 00 00 6b 00 00 00 0f 00 0d 00 00 0a 68 61 6f 2e 71 71 2e 63 6f 6d 00 05 00 05 01 00 00 00 00 00 0a 00 08 00 06 00 1d 00 17 00 18 00 0b 00 02 01 00 00 0d 00 1a 00 18 08 04 08 05 08 06 04 01 05 01 02 01 04 03 05 03 02 03 02 02 06 01 06 03 00 23 00 00 00 10 00 0e 00 0c 02 68 32 08 68 74 74 70 2f 31 2e 31 00 17 00 00 ff 01 00 01 00 16 03 03 00 be
Record Header 记录头
16 握手类型 0x16
03 03 协议版本为3.3(也称为TLS 1.2)
00 be 接下来是190字节的握手消息01 00 00 ba
Handshake Header 握手头
01 握手消息类型(客户端hello)
00 00 ba 接下来是186字节的客户端hello数据03 03
Client Version 客户端协议版本为3.3,也称为TLS 1.264 c4 d9 0a 37 40 a3 af d6 27 66 d1 bb 29 d0 53 c8 e0 dc 14 16 06 cf d1 1a 40 eb c0 d3 67 48 57
Client Random 32位客户端随机数00
Session ID 会话ID,长度为0表示没有会话ID00 26 c0 2c c0 2b c0 30 c0 2f c0 24 c0 23 c0 28 c0 27 c0 0a c0 09 c0 14 c0 13 00 9d 00 9c 00 3d 00 3c 00 35 00 2f 00 0a
Cipher Suites 密码套件
00 26 38字节的密码套件数据
c0 2c Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003d)Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)01 00
Compression Methods 压缩方法
01 1字节的压缩方法如下
00 0表示没有压缩00 6b
Extensions Length 扩展数据长度为107字节00 00 00 0f 00 0d 00 00 0a 68 61 6f 2e 71 71 2e 63 6f 6d 00 05 00 05 01 00 00 00 00 00 0a 00 08 00 06 00 1d 00 17 00 18 00 0b 00 02 01 00 00 0d 00 1a 00 18 08 04 08 05 08 06 04 01 05 01 02 01 04 03 05 03 02 03 02 02 06 01 06 03 00 23 00 00 00 10 00 0e 00 0c 02 68 32 08 68 74 74 70 2f 31 2e 31 00 17 00 00 ff 01 00 01 00
Extension 扩展数据
第二次握手:服务器发送
Server Hello 服务器Hello包
**Version **服务器端的版本号
Random 服务器端的随机数,用于生成密钥
Cipher Suite 服务器从浏览器密码套件中选择一个回复
**Compression Methods **压缩方法
**Extension **扩展数据
注意:
密码套件结构:密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法
_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 _
ECDHE 密钥交换算法(短暂-椭圆曲线-迪菲-赫尔曼)
RSA 签名算法,证书里的公钥用的是RSA算法,用于身份验证
AES_128_GCM 对称加密,数据加密,分组模式是 GCM
SHA256 数据摘要算法,用于证书的签名和验签
TLS_RSA_WITH_AES_128_GCM_SHA256 表示密钥交换算法和签名算法都是RSA
16 03 03 00 54
Record Header 记录头
16 握手类型 0x16
03 03 协议版本为3.3(也称为TLS 1.2)
00 54 接下来是84字节的握手消息02 00 00 50
Handshake Header 握手头
01 握手消息类型(服务器hello)
00 00 50 接下来是80字节的服务器hello数据03 03
Server Version 服务器协议版本为3.3,也称为TLS 1.254 49 db a3 2d d9 b1 6e d3 0d 05 4a c8 56 a1 1d 94 9b 2a f3 3c 75 e4 a9 a9 da e2 50 22 c8 7d 04
Server Random 服务器随机数00
Session ID 会话IDc0 2f
Cipher Suite 加密套件
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)00
Compression Method 压缩方法00表示不压缩00 28
Extensions Length 接下来扩展数据长度为40字节ff 01 00 01 00 00 00 00 00 00 0b 00 04 03 00 01 02 00 23 00 00 00 10 00 0b 00 09 08 68 74 74 70 2f 31 2e 31 00 17 00 00
Extension
Certificate 服务器的证书信息
包含X.509证书链,主证书第一个,之后是中间证书、根证书
证书包含:版本号、序列号、签名算法、颁发者、网站服务器公钥(RSA签名公钥)
用CA的私钥加密的证书的摘要信息,即证书签名
16 03 03 0b a8
Record Header
16 握手类型 0x16
03 03 协议版本为3.3(也称为TLS 1.2)
0b a8 接下来是2984字节的握手消息0b 00 0b a4
Handshake Header
0b 握手消息类型(服务器certificate)
00 0b a4 接下来是2980字节的服务器certificate数据00 0b a1
Certificates Length 证书链的长度为 2977字节00 06 8f
Certificate Length 第一个证书的长度为 1679字节30 82 06 8b 30 82 05 73 a0 ......
Certificate 证书内容00 05 0c
Certificate Length 第二个证书的长度为129230 82 06 8b 30 82 05 73 a0 ......
Certificate 证书内容
Server Key Exchange 密钥交换
**Curve Type **曲线类型
**Named Curve **曲线名称,选择x25519,即确定好椭圆曲线基点G
G确定好之后,服务器会生成一个随机数做为x25519的私钥Server PrivKey,保存在本地不公开,再根据G和Server PrivKey计算出椭圆曲线的公钥Server Pubkey(公钥/私钥都是临时的,只在本次会话中使用,图中的Pubkey)传送给客户端
为确保Pubkey不被中间人篡改,服务端会用RSA签名算法给Pubkey做个签名,RSA私钥保存再服务器,RSA公钥已经放在证书中传给客户端(签名算法是私钥签名,公钥验签)。
Server Hello Done 服务器所有握手信息都发送完毕
第三次握手:客户端发送
第三次握手之前,客户端会先验证服务器的证书
1、证书链是否可信
2、证书是否吊销
3、证书是否在有效期内
4、证书中的域名是否是当前要访问的域名
证书链的验证过程:
一般情况下,服务器向CA申请的证书不是根证书,而是中间证书签发的,所以客户端其实是拿到了一个证书链,百度的证书层次结构有三级:
1、客户端收到百度的证书后,发现这个证书的签发者不是根证书,就无法根据本地已有的根证书中的公钥去验证百度证书是否可信。于是,客户端根据百度证书中的签发者,找到该证书的颁发机构是GlobalSign RSA OV SSL CA 2018,然后向 CA 请求该中间证书。
2、请求到证书后发现GlobalSign RSA OV SSL CA 2018证书是由GlobalSign签发的,由于GlobalSign它是根证书,也就是自签证书。应用软件会检查系统中有没有预装CA根证书,如果有则可以利用根证书中的公钥去验证 GlobalSign RSA OV SSL CA 2018 证书,如果发现验证通过,就认为该中间证书是可信的。
3、GlobalSign RSA OV SSL CA 2018 证书被信任后,可以使用 GlobalSign RSA OV SSL CA 2018证书中的公钥去验证baidu.com证书的可信性,如果验证通过,就可以信任baidu.com证书
其实客户端最开始只信任根证书GlobalSign的证书,然后GlobalSign信任GlobalSign RSA OV SSL CA 2018,最后GlobalSign RSA OV SSL CA 2018又信任baidu.com证书,最终客户端也信任baidu.com证书
4、baidu.com证书可信后,客户端会得到RSA的公钥,并对服务端的Pubkey进行签名验证。
操作系统中保存的根证书
Client Key Exchange 客户端生成的椭圆曲线公钥发给服务器
证书验证通过后,客户端会根据服务器给的椭圆曲线算法生成一对自己的临时密钥Client PrivKey和 Client PubKey,并将Client PubKey用证书中的RSA公钥进行加密后发给服务器,就是图中的Pubkey
完成后客户端和服务端共享信息:Client Random、Server Random、椭圆曲线类型和名称、基点G、服务器椭圆曲线的公钥、客户端的椭圆曲线公钥。
此时客户端就可以计算会话密钥,会话密钥是基于对称加密的,会话密钥取决于主密钥,而组成主密钥的关键参数市预主密钥,密钥交换就是交换双方的预主密钥
1、客户端临时私钥、服务端临时公钥、以及椭圆曲线算法,计算出预主密钥(premaster secret),服务器也可以算出相同的预主密钥
pre_master_secret = ClientPrivKey * ServerPubKey
2、客户端随机数、服务端随机数、预主密钥,计算出主密钥(master secret)
PRF伪随机函数函数
master_secret = PRF(pre_master_secret, “master secret”, ClientHello.random + ServerHello.random)
3、客户端随机数、服务端随机数、主密钥 计算出最终的会话密钥,包含对称加密密钥,消息认证码密钥、初始化向量。
key_block = PRF(master_secret, “key expansion”, server_random + client_random)
因为 TLS 设计者不信任客户端或服务器「伪随机数」的可靠性,为了保证真正的完全随机,把三个不可靠的随机数混合起来,那么「随机」的程度就非常高了,足够让黑客计算出最终的会话密钥,安全性更高。
Change Cipher Spec 消息表示客户端已生成加密密钥,并切换到加密模式(密钥规格变更协议)
Encrypted Handshake Message 消息发送到服务器进行校验,这个对称加密密钥是否成功
客户端将之前所有的握手数据做一个HASH,再用最后协商好的对称加密算法对数据做加密。发送到服务器进行验证。
第四次握手:服务器发送
服务器在收到客户端Client Key Exchange消息后,这时可以拿到 Client Random、Server Random、客户端临时公钥Client PubKey,先计算出预主密钥(ClientPubKey * ServerPrivKey),再分别计算出主密钥和最终的会话密钥,这块可参考客户端计算密钥一样的。
New Session Ticket 服务器给客户端的Session ID,用于恢复会话
Change Cipher Spec 告诉客户端,服务端已生成密钥,请求客户端切换加密模式。
Encrypted Handshake Message 服务器对握手的所有数据用协商好的对称加密算法加密,供客户端校验。
此时整个握手完毕,已经建立一个安全的通信隧道,可以传输数据。
双方发送应用数据协议
整个握手过程完毕之后,我们会看到应用数据协议 “Application Data Protocol: http-over-tls”,之后我们的客户端/服务端建立一个安全通信隧道,就可以发送应用程序数据了。
在 RSA 握手中密钥交换:
1、客户端向服务器发送一条明文 “hello” 消息,其中包括他们要使用的协议版本、受支持的密码套件列表和称为“客户端随机数”的随机数据短字符串。
2、服务器使用其证书、首选密码套件和一个不同的随机数据短字符串(称为“服务器随机数”)响应(以明文格式)。
3、客户端验证证书,创建另一组随机数据46字节,称为“预主密钥(premaster secret)”。客户端从服务器的证书中获取公钥,加密预主密钥,并将其发送到服务器;只有拥有私钥的人员才能解密预主密钥。
4、该服务器解密“预主密钥”。注意,这是唯一一次使用私钥!
5、客户端和服务器都有客户端随机数、服务器随机数和预主密钥。根据这三个数计算得到主密钥,再通过主密钥计算得到会话密钥,会话密钥市对称的,会话期间的所有后续通信都用这些新会话密钥进行加密。
前向安全性问题:
RSA密钥交换的简单性也是它最大的弱点。用于加密预主密钥的服务器公钥,一般会保持多年不变。任何能够接触到对应私钥的人都可以恢复预主密钥,并构建相同的主密钥,从而危害到会话安全性。
对目标的攻击并不需要实时进行,强大的对手可以制定长期行动。攻击者会记录所有加密的流量,耐心等待有朝一日可以得到密钥。比如,计算机能力的进步使暴力破解成为可能;也可以通过法律强制力、政治高压、贿赂或强行进入使用该密钥的服务器来取得密钥。只要密钥泄露,就可以解密之前记录的所有流量了。
TLS中其他常见的密钥交换方式都不受这个问题的影响,被称为支持前向保密。使用那些密钥交换时,每个连接使用的主密钥相互独立。泄露的服务器密钥可以用于冒充服务器,但不能用于追溯解密任何流量。
为什么HTTPS的包可以被抓到?
首先抓包之前,fiddler会提示安装自己的根证书到操作系统(我们主动把它添加到了受信任的根证书颁发机构,所以我们计算机是认可这个证书的)
1、fiddler截获客户端发送的HTTPS,然后伪装成客户端向服务器发送请求
2、服务器返回数据,fiddler截获服务器的CA证书,用跟证书的公钥进行解密,验证服务器数字签名,获取服务器CA证书的公钥,然后fiddler伪造自己的CA证书,冒充服务器证书发给客户端,此时Fiddler就是中间人,可以截获客户端和服务器之间的数据。
3、Fiddler的根证书是能抓包的关键,这也是Fiddler伪造的CA证书能够获得客户端和服务器端信任的。