Https简要流程:
- 先TCP握手建立连接
- 在TCP上再TLS/SSL握手建立加密通道
- 最后在TLS/SSL通道上传输加密Http应用数据。
这里重点研究TLS(基于1.2版本)的握手部分。
TCP握手见之前文章,一些基本概念如对称加密、非对称加密、基础网络知识等文中略。
参考资料:
TLS WIKI
TLS1.2 RFC
TLS握手简略流程
- 互相hello。确定算法,交换随机数
- 交换参数用以协商 pre_master_secret(RSA、DHE)
- 交换证书,互相验证(通常只验证服务端的,去CA机构验证)
- 双方根据互换的随机数和pre_master_secret,生成相同的对称加密秘钥
- 互相确认已经切换到加密通话模式,且握手期间信息未被篡改
TLS握手详细流程
以访问 https://www.zhihu.com 为例,C=Client,S=Server
- C ClientHello:支持tls最高版本,随机数1,可用加密列表,期望session ID(可空)
- S ServerHello:选择共同支持tls最高版本,随机数2,从可用表中选择加密算法,确定session ID(新建or复用)
- S Certificate 证书:证书链(主到根),证书公钥subjectPublicKey,证书签名encrypted
- S ServerKeyExchange 交换秘钥(ECDHE):椭圆曲线,公钥pubkey,签名
- S ServerHelloDone 服务端Hello流程结束。
- C ClientKeyExchange 交换秘钥:公钥pubkey
- C ChangeCipherSpec 告知后续使用加密沟通
- C EncryptedHandshakeMessage 将整个握手期间的信息摘要加密后发给对方,以确认双方秘钥匹配,同时保证期间数据未被篡改
- S ChangeCipherSpec 同上
- S EncryptedHandshakeMessage 同上
秘钥协商流程详细介绍
对称秘钥的协商是TLS握手中的重点,可以有不同方案,以我们访问知乎为例。在ServerHello时,服务端选择了:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- 对称秘钥协商:ECDHE
- 证书验证:RSA
- 对称加密:AES_128_GCM
- 摘要:SHA256
对称秘钥协商以前会用RSA,但RSA不具有前向安全性,现在TLS1.2大部分都使用ECDHE。
不同协商方案
- RSA
- S ServerKeyExchange:无此步骤
- C ClientKeyExchange:生成PreMaster,用服务端证书里公钥加密后发送
- S 收到加密PreMaster,用对应秘钥解密
- 双方根据之前hello互传的俩随机数和PreMaster生成相同的秘钥用于对称加密
- DHE
- S ServerKeyExchange:发送公共数p和g,然后用私密数key1计算 g^key1 mod p 放在 pubkey里发给客户端
- C ClientKeyExchange:用服务端发来的p和g,以及自己的私密数key2计算,g^key2 mod p 放在pubkey发给服务端
- 双方根据对方的pubkey^key1/2 mod p 计算出同样的 PreMaster,再连同随机数一起生成对称加密秘钥
- ECDHE 基于DHE,使用椭圆曲线数学法替代mod计算
- S ServerKeyExchange:指定椭圆曲线;服务器本地计算个大数key1 乘以曲线的base point 得到新的point,作为pubkey
- C ClientKeyExchange:使用同样曲线,同理客户端本地计算个key2生成pubkey
- 双方根据对方的pubkey再结合自己的key利用曲线计算得到同样的 PreMaster,再连同随机数一起生成对称加密秘钥
协商方案对比
- DHE和ECDHE对比:
- 都是基于DHE,流程基本相同,都是协商秘钥算法。但具体算法不同,一个是基于mod一个是基于椭圆曲线。
- DHE(ECDHE)和RSA对比:
- RSA的对称加密秘钥发送是单向的C->S,无ServerKeyExchange步骤。而DHE需要互换pubkey所以需要双向KeyExchange。
- RSA不需要签名,本身PreMaster就是用公钥加密的,C->S中途如果有篡改,服务端的秘钥解析会出错。而DHE中有S->C时中途被篡改p,g的可能,因此在ServerKeyExchange里会携带一个数字签名,客户端收到后验证是否被篡改。ClientKeyExchange 时无需签名,因为只会传递pubkey,拦截了也无法知晓各自的私密数字。
- RSA不具备前向安全性,秘钥丢失后攻击者可以解密旧的会话信息。DHE具备前向安全性。
- DH和DHE对比:
- 普通DH协议是不具有前向安全性的,它会在证书中携带公共数字(因此不需要ServerKeyExchange步骤),服务端自己持有对应私密数字,这一对是固定的,如果丢失私密数字依然会暴露旧的会话信息。
- DHE(E=ephemeral短暂)具有前向安全性。它不在证书中携带DH参数,由服务端在每次会话中生成新的,这样即使攻击者拿到RSA证书的秘钥去反推得到某次会话的公共数,但也无法知晓那次会话双方的私密数,也就无法计算对称秘钥,因此是前向安全的。
DH原理简述
RSA 是一种非对称加密算法,此处略过不做详细介绍。
Diffie-Hellman 是一种秘钥协商的算法(不是加密算法),详细可以参考 Diffie-Hellman WIKI
大概原理可以参考上图
- 双方有个共享色(黄),然后各自持有一份私密颜色(A橘红色,B绿色)
- 双方把自己的私密颜色和共享色混合(A土黄色,B蓝色)后再互传
- 双方把对方发过来的混合色和自己的私密颜色再次混合,得到相同的颜色(双方都是:公共黄色+A私密颜色橘红色+B私密颜色绿色=棕色),最后以棕色作为对称秘钥加密信息互通
双方颜色的累加都一样,所以最后是同样的颜色,但混合的颜色互传时别人是无法反推私密颜色的。在DHE实际算法中,mod或椭圆曲线法都可以类比Hash、MD5等离散算法(只是便于理解,DHE实际上更特殊),你拿到结果但是无法反推源数据,就像混合色无法反推私密色,达到安全目的。
Wireshark 抓包
以访问 https://www.zhihu.com 为例
总体流程
Client Hello
Server Hello
Server Certificate
Server Key Exchange
Client Key Exchange
其它简单的步骤图略
问题链‰
-
为什么要Https?
Http不安全,会被监听、篡改、钓鱼冒充 -
如何防止监听?
用对称加密算法,发送端秘钥加密,接收端同一个秘钥解密 -
如何交换对称加密秘钥?
方法一:RSA非对称加密,客户端用服务端给的公钥加密「对称秘钥」发给对方,服务端用对应秘钥解密获取
方法二:Diffie-Hellman 秘钥协商 -
RSA如何确定公钥是否正确?
去CA验证 -
如何确定数据是否被中途篡改?
服务端返回数据携带数字签名,签名是将报文信息计算摘要后再用私钥加密。接收端将报文计算摘要,再用对应公钥解密签名对比摘要是否相同,以此验证完整性 -
签名验证的公钥如何确定是否正确?
去CA验证(由此可见RSA作为一种对称加密算法,即可以传输秘钥用,也可以验证数字证书用) -
和CA认证也是一次网络请求,如何保证安全?
主机系统预装CA机构公钥,不走网络获取公钥,保证安全 -
为什么TLS交换对称秘钥使用DHE而非RSA?
DHE具有前向安全性,RSA不具备。