了解 HTTPS 的TLS过程

2,959 阅读7分钟

前言

HTTPS中是先TCP三次握手还是先TLS证书校验?

HTTPS中密钥协商的过程是使用的RSA加密算法吗?

对于这两个问题,看了很多的博客,写的都不一致,今天来自己验证一下!

准备分析工具

WireShark 介绍

一个抓包网络的分析软件,可以截取各种网络数据包。

通过它可以看到物理层数据链路层ip层TCP层TLS层HTTP层的数据信息。

因此,我们这次准备使用WireShark工具去尝试看到包括TCP的实际过程。

PS:大家熟悉最多的可能还是Charles,但是Charles的原理是依靠中间人的方式,将请求和响应的信息呈现出来。我们只能看到应用层的信息,无法研究更深入的信息,因此这里不使用。

WireShark下载地址

WireShark使用

打开界面如下: image.png

点击Capture Options

image.png

选择要监听的端口,点击“start

就可以看到所有的TCP等信息了。

image.png

但是这里我们决定不使用电脑来抓包。因为电脑支持多进程,干扰信息太多了,看的眼花缭乱。

iphone可以选择只打开一个应用,这样方便分析。

iPhone手机使用WireShark抓包

第一步拿到 设备udid
  • 如果电脑上有Xcode:手机连接电脑,打开Xcode,选择Window -> Device and Simulators 就可以看到。

  • 如果没有,可以使用第三方的服务。比如蒲公英获取UDIDfir.im获取UDID都可以。

然后执行
rvictl -s iphone设备id 

(PS: rvictl -x 设备id 是关闭连接的意思)

选择wireshark里的Cature Option中的riv0

image.png

然后在手机上打开任意App,就可以查看里面的信息。

image.png

分析过程

从上面信息,我们可以看到真正开始发数据之前,ClientServer的信息交换如下图:

image.png

这里能回答开篇的第一个问题:

先是经过TCP三次握手,建立连接后,才开始TLS握手(这里很多博客上写的是错误的)。

为什么Wireshark的数据图里,在Server Hello,证书交换等步骤之前,都有一个TCP数据传递?

因为证书这些信息的交换本来就是基于TCP连接来传输的,所以一定是先建立TCP连接,然后利用TCP通道进行证书等信息的传递。

image.png 从上图可以看到Server Hello上面的TCP的序号和 Server Hello 点开后的TCP的序号是一致的

具体TLS的握手详情

  • Client Hello

    Client需要告诉对方: 自己的TLS版本,自己支持的密码套件,自己生成的随机数 image.png

  • Server Hello

    Server告诉对方,自己确认的TLS版本,随机数,选择的密码套件

image.png

  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

  密钥协商算法:ECDHE

  签名算法:RSA

  握手后的通信使用 AES-128,分组模式GCM

  摘要算法使用:SHA384
  • Certificate,Server Key Exchange, Server Hello Done

image.png

 1.Server给对方自己的证书来表明身份。证书是使用sha256摘要和RSA加密过的。

 2.进行key的交换。告诉对方ECDHE算法里的相关信息。

 3.发送Server Hello Done信息
  • Client Key ExchangeChange Cipher SpecEncrypted 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`函数来校验。

下面是这个函数的信息:

image.png

从该方法的介绍看,应该是会先访问缓存结果,然后是通过网络访问证书信息和吊销证书列表。

这是一个耗时操作,到这里就会牵扯出一个HTTPS的优化点(利用服务端定期进行OCSP,然后将信息返回给应用,这样就解决了Client经常去校验的情况)

系统的证书信息,感觉苹果会定时去请求获取的。因为抓包过程中,经常会偶尔发现这个请求:

image.png

应该是定期更新证书信息到本地.

好了,关于HTTPS的TLS过程就介绍到这里,欢迎大家指出不妥之处。

本文参考链接:

www.it163.com/support/133…

www.likecs.com/default/ind…