分享

基于Wireshark抓包浅谈对HTTPS的理解(TLS、SSL、数字证书、数字签名)

 木易81 2022-08-17 发布于天津

简单记录一下近日学习HTTPS、TLS等协议的收获和心得。

1. HTTPS定义

超文本传输安全协议(英语:HyperText Transfer Protocol Secure,缩写:HTTPS;常称为HTTP over TLS、HTTP over SSL或HTTP Secure)是一种通过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,但利用SSL/TLS来加密数据包。HTTPS开发的主要目的,是提供对网站服务器的身份认证,保护交换资料的隐私与完整性。

2. HTTPS与HTTP的区别

  • HTTP的URL是由“http://”起始与默认使用端口80,而HTTPS的URL则是由“https://”起始与默认使用端口443。

  • HTTP基于明文传输,不安全,攻击者可以通过监听和中间人攻击等手段,获取网站帐户和敏感信息等。HTTPS的设计可以防止前述攻击,在正确配置时是安全的。

3. 加密算法

在介绍HTTPS之前,首先来说一下加密算法。加密算法有双向和单向之分,双向加(解)密算法指明文和密文可相互转化,单向加密算法则只能由明文转化为密文,无法逆向转化。下图是两种分类所主要用到的算法。

其中来着重介绍对称加密和非对称加密,以及二者的结合。

3.1 对称加密

可以用一组公式来总结:

f1(k, data) = encrypted_data
f2(k, encrypted_data) = data

其中f1f2分别为加密,解密算法。k为密钥,data为明文数据,encrypted_data为加密数据。

流程:客户端和服务器共同协商出一个密钥和一个对称加密算法,后面传输数据时利用密钥和对称加密算法对数据进行加密,另一端收到后,利用解密算法得到原始明文数据。

3.2 非对称加密

非对称加密有公钥(public_key)和私钥(private_key),二者一一对应,在生成私钥的同时也生成对应公钥。

公式总结如下:

f(pub_key, data1) = encrypted_data1
f(pri_key, encrypted_data1) = data1
-------------------------------------
f(pri_key, data2) = encrypted_data2
f(pub_key, encrypted_data2) = data2

其中pub_keypri_key 分别为公钥和私钥。通过公钥和私钥都可以给数据加密,且使用对应的私钥/公钥可对数据解密。

流程:客户端向服务器发出请求索要公钥,服务器返回公钥。客户端将数据通过公钥加密后发给服务器,服务器通过私钥进行解密;服务器通过私钥对数据加密后发给客户端,客户端利用公钥解密。

3.3 对称加密 + 非对称加密

非对称加密的效率,对称加密的安全性是其二者的缺点,所以可以将二者结合,实现取长补短。

流程:客户端向服务器发出请求索要公钥,服务器返回公钥。客户端随机生成一个随机数num,num通过公钥加密后发送给服务器,服务器利用私钥解密,得到num。这时,客户端和服务器将num共同视为对称加密的密钥,后面传输的数据通过此密钥加/解密。

4. 数字证书和数字签名

在接收到数据包时,会出现一个问题:如何确定此数据包是不是真正目的服务器所发出的(中间人攻击会冒充服务器,向客户端发送数据包、公钥)。这时就需要「数字签名」和「数字证书」技术来验证文件内容的一致性与服务器的身份(安全性更高的场景还需要验者客户端的身份)。数字签名算法主要有RSA(哈希算法 + RSA加密算法),DSA,ECDSA。

  1. 小明首先生成公钥和私钥,将文件内容进行哈希运算得到文件摘要(文件哈希值),再利用私钥和RSA加密算法对摘要加密,得到数字签名。

  2. 小明将文件、公钥、数字签名发送至小红,小红接收到网络包,利用拿到的公钥对数字签名解密,得到文件摘要1(文件哈希值);对文件进行哈希运算,得到文件摘要2。摘要1和摘要2相同则签名成立,反之不成立。摘要1和摘要2相比较这一步可确保文件在传输过程中不被篡改(若文件被篡改,文件哈希运算得出的摘要2与解密签名得到的摘要1不同)。

  3. 又引出了一个问题:小红如何确保得到的公钥一定是小明生成的?

    小明将其公钥和部分身份信息发送给CA(Certificate Authority),CA在核实小明身份后,颁发数字证书(确保公钥和小明的一一对应关系),小明只需要将数字证书一起发送给小红,小红即可确定收到的公钥是否为小明生成。

  4. 如何确保数字证书不被篡改?

    CA有自己的公钥和私钥,通过私钥对小明的文件、公钥进行哈希摘要 + RSA加密,得到CA的数字签名,放在小明的数字证书中,而CA根证书为了不被伪造,被嵌在客户端和服务端的操作系统或浏览器中。

    在实际环境中,服务器发来的证书通常会有多个证书组成证书链。例如:根 CA 证书 -> 中级 CA 证书 -> 服务端证书。客户端在验证服务端证书的有效性有这样的一个过程。首先会找到该证书的认证证书,也就是中级 CA 证书。然后找中级 CA 证书的认证证书,可以是另一个中级 CA 证书,也可能是根 CA 证书,这样直到根 CA 证书。接着从根 CA 证书开始往下去验证数字签名。用 CA 证书的公钥去验证中级证书的数字签名,再用中级证书的公钥去验证服务器证书的数字签名。任何一个环节验证失败,就可以认为证书不合法。

5. TLS握手

TCP 三次握手结束和服务器成功连接后,客户端就开始发起TLS连接,首先会进入**TLS握手阶段**。

TLS握手阶段目的:

  • 协商加密密钥

    用来对后面的 HTTP 协议等应用协议内容进行加密。这个密钥又称为主密钥,为加密算法的密钥。

  • 协商加密算法

    为了能够提供效率,使用对称密钥。对称加密使用的是位运算,速度快,甚至可以硬件加速。非对称加密比如 RSA,使用了大数乘法等,整体会比较慢。对称加密只要密钥没有泄漏,那也是非常安全的。这也是后面 SSL 握手协议要确保的。

  • 验证身份及数据完整性

    通常情况下,只要验证服务端身份。特殊情况下,比如一些安全级别高的应用场景,还要验证客户端身份。服务端会返回证书链,有根 CA 证书在里头。通过证书的链式担保,可以确认服务端是否是可信任的。同时,在握手期间,公钥传输成功后,还会对某些信息进行数字签名,确保数据没有被篡改且身份无误。

TLS握手阶段一般流程(TLS握手的流程并不是一成不变的,根据实际的应用场景来,主要有三种):

  • 只验证服务端

    这个用三个阶段就完成握手,此次Wireshark的请求也是这样。一般的网络请求也仅仅到这个程度。

  • 验证服务端和客户端

    在安全性要求较高的场景,服务端也要验证客户端的身份。方式也是发证书证明自己。

  • 恢复原有会话

    这个属于HTTPS 优化的范畴。使用 Session Ticket 或者 Session ID 机制恢复之前已经完成握手的会话。这个是可以允许在不同的 TCP 上进行的。因为握手的加密数据已经保存,直接恢复就可以开始传递了。Session Ticket 由客户端保存加密信息,Session ID 的方式由服务端保存加密信息。不过 Session Ticket 在 Android 客户端还没有得到广泛的支持,和具体机型和内置的 OpenSSL 的版本有关。

TLS握手机制图解

Client Hello

在Wireshark软件中捕获了访问知乎网页数据包,追踪TCP流得到第一个TLS包

  • 类型

  • 长度

  • 版本

    TLS 1.2 也是 SSLv3.2。这是 SSL 客户端能够支持的 SSL 最高版本

  • 随机数

    生成一个32字节随机数(图中的随机数1)。最后加密数据用的主密钥,需要客户端和服务端一起协商出来。后面服务端的 Server Hello 阶段也会生成一个随机数。一同用来计算出主密钥。

  • 会话ID

    这个 Session ID 是可以重用的,具体看服务端资源和支持情况。如果要复用 Session ID, SSL 服务端需要维护连接的状态和上次握手成功留下的加密信息。如果是第一次访问该网址,会话 ID 尚未创建,客户端没记录,为 0。如果客户端保存了 Session ID 的信息,下次发起 SSL 请求的时候会带上。

  • 加密套件

    客户端可以支持的密码套件列表。这些套件会根据优先级排序。每一个套件代表一个密钥规格。以 “TLS” 开头,接着是密钥交换算法,然后用 “WITH” 连接加密算法和认证算法。一个加密套件有这么几个内容:密钥交换算法、加密算法(会带有支持的最高密钥位数)、认证算法还有加密方式。最终使用什么密码套件是服务端决定的。要什么密码套件会在 Server Hello 中进行反馈。

  • 压缩算法

    这里为 0,说明不支持压缩算法

  • 扩展字段

    一些扩展信息,比如 SNI 的支持,ALPN 的信息等等

Server Hello

  • 类型

  • 版本

    指定这次 SSL 使用 TLSv1.2 版本

  • 随机数

    上面的 Client Hello 过程也生产了一个 32 位随机数,这两个随机数将参与主密钥(master key)的创建。(对应图解中随机数2)

  • 会话ID

  • 加密套件

    TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 。这个是从客户端 Client Hello 上传的加密套件中选中的,根据密码套件的格式,上面的信息有,

    • 交换加密算法为ECDHE ,就是EC Diffie-Hellman ,RSA 表示后面 Server Key Exchange 阶段的携带 DH 加密算法的公钥的包的数字签名的加密算法是 RSA;

    • 加密算法为 AES ,最高密钥支持 128 位

    • 认证算法 SHA256

  • 压缩方法

    这里为 0,表示不使用压缩算法

Certificate

服务端下发证书,客户端验证服务端的身份,并且取出证书携带的公钥,这个公钥是交换加密算法的公钥。也就是在 Server Hello 阶段指定的 ECDHE (EC Diffie-Hellman)算法,也是通常说的 DH 加密。

这个 Certificate 消息下发了从携带自己公钥的数字证书和 CA 证书的证书链,在 Certificates 字段中:

由字段信息可知,证书链中共有3个数字证书。分别为服务端(zhihu.com)证书 -> 中间CA证书 -> 根CA证书。首先看服务端证书

首先是 signedCertificate 字段的内容,即数字证书的数据

  • 版本

    对应的就是 X.509 V3 标准

  • 序列号

    serialNumber,证书颁发者唯一序列号。

  • 签名算法ID

    这里指的是使用 SHA-256 进行摘要,RSA 进行加密的签名算法。

  • 证书颁发者

    issuer,就是颁发该证书的 CA 的信息。里面携带后该 CA 的唯一名称(DN,Distinguished Name),比如国家为 US(美国),组织机构为 DigiCert Inc.,名称为 GeoTrust CN RSA CA G1。后面我们需要从证书链找到该 CA 证书(具体方法:在其他证书的subject字段查找国家、组织机构、名称),去认证当前证书

  • 有效期

    validity,证书的起始时间和终止时间

  • 对象名称

    subject,里面就是该证书的名称等主要信息了。比如国家为 CN(中国),组织为智者四海(北京)技术有限公司。名称为 *.zhihu.com ,也是该证书适用的域名。

  • 对象公钥信息

    subjectPublicKeyInfo。因为这是服务端证书,这个公钥后面将用于主密钥的交换过程,从中可以了解到这个公钥采用 RSA 加密

  • 扩展部分

    一些扩展信息。比如对象的别名。这个如果是 CDN 的服务器证书,那么别名将会非常多。

然后是证书颁发机构的签名信息:

  • 签名算法

    algorithmIdentifier,这里得出使用的还是 SHA-256 摘要加 RSA 加密的签名算法。这个就是认证该证书的 CA 证书使用的签名算法。

  • 签名信息

    encrypted,这个信息的内容,CA 证书对 SHA-256 对上面的数据部分进行摘要后,使用 RSA 的私钥加密获得。后面会用在该证书的认证过程,取出 CA 证书的公钥,解密签名信息,用同样的算法获取数据摘要,对比一下是否相同。

Server Key Exchange

密钥交换阶段,这个步骤是可选步骤,对 Certificate 阶段的补充,只有在这几个场景存在:

  • 协商采用了 RSA 加密,但是服务端证书没有提供 RSA 公钥。

  • 协商采用了 DH(EC Diffie-Hellman) 加密,但是服务端证书没有提供 DH 参数。

  • 协商采用 fortezza_kea 加密,但是服务端证书没有提供参数。

Server Hello Done

通知客户端,版本和加密套件协商结束。

通过 Wireshark 抓包发现了一个现象,就是 Server Key Exchange 和 Server Hello Done 被放到了同一个 SSL 记录协议中,这是因为 SSL 记录协议具有组合功能。客户端收到这样的包后,会处理成两个单独的协议包,这又是 SSL 记录协议的分组功能。

Client Key Exchange

这里,客户端不直接生成加密密钥,而是通过之前客户端和服务端生成的随机数又再生成一个随机数,使用前面协商好的用 EC Diffie-Hellman 算法进行加密传输给服务端。这个值又被称为 “premaster secret“。

服务端收到这个报文后,会使用自己的私钥解开这个随机数。在这个阶段过后,服务端和客户端都有三个随机数:客户端随机数、服务端随机数和预备主密钥。在服务端收到了 Client Key Exchange 消息后,两端都按照相应的算法生成了主密钥,加密密钥交换完成。交换完了,因为主密钥是两个端按照约定好的算法产生的,如何保证这个主密钥是正确的?这时候会进入下一个阶段。客户端和服务端会对握手信息使用 SHA 做个摘要,用 AES 加密算法和主密钥加密,传递给对方验证。这种方式也称为消息认证。就是下面的过程:

Change Cipher Spec (Client)

客户端通知服务端,后续的报文将会被加密。

Encrypted Handshake Message (Client)

这里就是客户端的 Client Finished 消息。也是整个 SSL 过程中,发送给服务端的第一个加密消息。服务端接收后,服务端用同样的方式计算出已交互的握手消息的摘要,与用主密钥解密后的消息进行对比,一致的话,说明两端生成的主密钥一致,完成了密钥交换。

Change Cipher Spec (Server)

服务端通知客户端,后续的报文将会被加密。

Encrypted Handshake Message (Server)

这里就是服务端的 Server Finish 消息。和上面的客户端的 Encrypted Handshake Message 一样,是服务端发出的第一条加密信息。客户端按照协商好的主密钥解密并验证正确后,SSL 握手阶段完成。

Application Data

应用数据传输消息。因为这里是 HTTPS,所以可以对 HTTP 应用协议数据加密然后传输了。

6. 参考资料

Wireshark 抓包理解 HTTPS 请求流程

HTTPS原理全解析

2分钟掌握 HTTPS原理和 TLS 握手机制

数字签名 及 数字证书 原理

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多