前言
HTTPS中是先TCP三次握手还是先TLS证书校验?
HTTPS中密钥协商的过程是使用的RSA加密算法吗?
对于这两个问题,看了很多的博客,写的都不一致,今天来自己验证一下!
准备分析工具
WireShark
介绍
一个抓包网络的分析软件,可以截取各种网络数据包。
通过它可以看到物理层
,数据链路层
,ip层
,TCP层
,TLS层
,HTTP层
的数据信息。
因此,我们这次准备使用WireShark
工具去尝试看到包括TCP
的实际过程。
PS:大家熟悉最多的可能还是Charles
,但是Charles
的原理是依靠中间人的方式,将请求和响应的信息呈现出来。我们只能看到应用层的信息,无法研究更深入的信息,因此这里不使用。
WireShark
的下载地址
WireShark
使用
打开界面如下:
点击Capture Options
:
选择要监听的端口,点击“start
”
就可以看到所有的TCP
等信息了。
但是这里我们决定不使用电脑来抓包。因为电脑支持多进程,干扰信息太多了,看的眼花缭乱。
iphone可以选择只打开一个应用,这样方便分析。
iPhone手机使用WireShark
抓包
第一步拿到 设备udid
-
如果电脑上有Xcode:手机连接电脑,打开Xcode,选择Window -> Device and Simulators 就可以看到。
-
如果没有,可以使用第三方的服务。比如蒲公英获取UDID,fir.im获取UDID都可以。
然后执行
rvictl -s iphone设备id
(PS: rvictl -x 设备id
是关闭连接的意思)
选择wireshark
里的Cature Option
中的riv0
然后在手机上打开任意App
,就可以查看里面的信息。
分析过程
从上面信息,我们可以看到真正开始发数据之前,Client
和Server
的信息交换如下图:
这里能回答开篇的第一个问题:
先是经过TCP三次握手,建立连接后,才开始TLS握手(这里很多博客上写的是错误的)。
为什么Wireshark的数据图里,在Server Hello,证书交换等步骤之前,都有一个TCP数据传递?
因为证书这些信息的交换本来就是基于TCP连接来传输的,所以一定是先建立TCP
连接,然后利用TCP
通道进行证书等信息的传递。
从上图可以看到Server Hello
上面的TCP
的序号和 Server Hello
点开后的TCP
的序号是一致的
具体TLS的握手详情
-
Client Hello
Client
需要告诉对方: 自己的TLS
版本,自己支持的密码套件,自己生成的随机数 -
Server Hello
Server
告诉对方,自己确认的TLS
版本,随机数,选择的密码套件
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
密钥协商算法:ECDHE
签名算法:RSA
握手后的通信使用 AES-128,分组模式GCM
摘要算法使用:SHA384
- Certificate,Server Key Exchange, Server Hello Done
1.Server给对方自己的证书来表明身份。证书是使用sha256摘要和RSA加密过的。
2.进行key的交换。告诉对方ECDHE算法里的相关信息。
3.发送Server Hello Done信息
-
Client Key Exchange
,Change Cipher Spec
,Encrypted HandShake Message
1.
Client
校验对方的证书,判断是否合法2.进行
key
的交换,告诉对方ECDHE
算法里的自己的信息3.通过 客户端随机数 + 服务端随机数 + ECDHE算法算出来的共享密钥 生成最终的会话密钥。
4.告知对方,后面使用对称加密算法通信。
5.发送
Encryted Handshake Message
消息,将之前发送的数据做一个摘要,使用对称密钥加密一下,让服务端做个验证。 -
Change Cipher Spec,Encrypted Handshake Message
Server
端根据ECDHE
里的信息,也计算出会话密钥,发送这两个消息给对方。
如果双方都验证ok,那么握手正式完成。
从上面的证书交换信息里,可以看到协商密钥的算法使用的 ECDHE
算法 。目前大部分都是使用ECDHE
算法来进行密钥协商,抛弃RSA
的原因是其不具备向前安全性。
使用ECDHE
算法,每次证书协商都是随机生成的信息。即使这一次的加密被破解了,也不会影响其他请求的安全性。但是如果是用RSA
,破解了一次,那么除非更换公私钥,否则所有的请求都不安全了。
问题
为什么要加入TLS层?
HTTP
协议是明文传输,并且不进行对方身份校验,容易被劫持,篡改,中间人拦截,信息泄漏等等。
因此一定要加入防护手段。
为什么不直接使用对称加密方式?
对称加密算法。比如AES
算法:安全性高,性能也好。
但是最大的问题是:如何把密钥给到对方?
首先不能内置到Client端,因为密钥容易被获取。并且后续无法进行实时更换。
所以一定要想办法传输给对方。
但是又如何保证安全传输
密钥信息呢?
为什么不全部使用非对称加密?
非对称加密,非常的安全。公钥可以解密私钥加密的数据,私钥可以解密公钥加密的数据。
公钥是公开的,所以传递公钥的问题得以解决了。
但是非对称加密的算法,性能消化比对称加密大,不适合数据传递实时加解密。
因此可以使用混合加密的方式。 公钥的传递使用非对称加密,后续数据的加解密使用对称加密算法。
为什么还要涉及到摘要算法?
摘要算法可以对传输内容进行摘要,这个过程不可逆。可以用来防止内容被篡改,保证内容的完整性。
但是这样的方式只解决了数据通信的问题。如何保证和你协商密钥的人是不是你认为的那个人呢?
如果一个人冒充Server
和你交流,那么你的数据岂不是全部到人家手中了?
所以,Client
无法相信任何人的。
那这怎么办呢?
第三方公信机构 CA (Certificate Authority ,证书认证机构)
它就像网络世界里的公安局、教育部、公证中心,具有极高的可信度,由它来给各个公钥签名,用自身的信誉来保证公钥无法伪造,是可信的。CA 对公钥的签名认证也是有格式的,不是简单地把公钥绑定在持有者身份上就完事了,还要包含序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证明公钥关联的各种信息,形成“数字证书”(Certificate)
但是需要保证CA没问题。
它存在两个问题。
-
基于
CA
签发的证书,可能是错误的,过期的,无效的。可以使用
CRL
(证书吊销列表) 和OCSP
(在线证书状态)来解决。 -
黑客攻陷了
CA
需要操作系统或者浏览器撤销对该
CA
的信任。
iPhone手机中的APP如何校验服务端给的证书?
这里我们通过AFNetworking
代码作为入口来查看。
查看AFSecurityPolicy.m
文件中的- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain
通过AFServerTrustIsValid
函数来校验。
这一步会通过系统的`SecTrustEvaluate`函数来校验。
下面是这个函数的信息:
从该方法的介绍看,应该是会先访问缓存结果,然后是通过网络访问证书信息和吊销证书列表。
这是一个耗时操作,到这里就会牵扯出一个HTTPS
的优化点(利用服务端定期进行OCSP
,然后将信息返回给应用,这样就解决了Client
经常去校验的情况)
系统的证书信息,感觉苹果会定时去请求获取的。因为抓包过程中,经常会偶尔发现这个请求:
应该是定期更新证书信息到本地.
好了,关于HTTPS的TLS过程就介绍到这里,欢迎大家指出不妥之处。
本文参考链接: