Wireshark抓包微信Web详细分析HTTPS通信中TLS/SSL工作原理

简介

HTTPS

HTTPS(Hypertext Transfer Protocol Secure)是一种网络安全传输协议,是一种用于在不可信网络上进行安全通信的传输协议,HTTPS经由HTTP进行通讯,使用SSL/TLS协议对数据进行加密。主要为解决以下三点问题。

  • 通信双方的身份验证
    例:登录微信输入用户或与密码,如何保证确实是在向微信官方发送信息?
  • 通信数据的私密性
    例:用饭店wifi微信聊天,店内的人可否看到?
  • 通信数据的完整性
    例:吃饭微信支付100,能否让实际扣款666,当时显示消费还是100?

TLS/SSL

SSL安全套接层(Secure Sockets Layer)与TLS传输层安全协议(Transport Layer Security)都是一种用于保障数据安全传输的协议。
SSL由网景公司(Netscape)公司设计,一直发布到SSLv3.0版本,后面其有安全漏洞被许多公司禁用。
TLS由IETF发布,SSL是TLS的前身。
下面是其发布时间表:

协议年份
SSL 3.01996
TLS 1.01999
TLS 1.12006
TLS 1.22008
TLS 1.3待定

TLS/SSL在OSI或TCP/IP模型中的层级

那么TLS/SSL位于OSI或TCP/IP模型中的哪一层呢?以下取自维基百科

TLS and SSL are defined as ‘operating over some reliable transport layer’, which places them as application layer protocols in the TCP/IP reference model and as presentation layer protocols in the OSI model.

结合下图及上面描述可看出,在OSI模型中TLS/SSL位于表现层,在HTTP(应用层)协议之下。
这里写图片描述

TLS/SSL握手协议工作原理

总体流程如下,用*号标注的是可选流程:

Client                                               Server
  ClientHello                  -------->
                                                  ServerHello
                                                 Certificate*
                                           ServerKeyExchange*
                                          CertificateRequest*
                               <--------      ServerHelloDone
  Certificate*
  ClientKeyExchange
  CertificateVerify*
  [ChangeCipherSpec]
  Finished                     -------->
                                           [ChangeCipherSpec]
                               <--------             Finished
  Application Data             <------->     Application Data

Hello Request(可选)

Hello Request是一个用于通知客户端需要重新发起握手的简单通知,客户端可以以
ClientHello相回应,也可以忽略,服务器在任何时间都可以发送此消息。
这里写图片描述

Client Hello

客户端要建立HTTPS连接时会发送一个ClientHello消息,消息体结构如下:

struct {
ProtocolVersion client_version; //客户端支持的TLS最高版本
Random random; //客户端生成的随机数(暂命名client_hello_random),用于之后生成会话密钥
SessionID session_id;
CipherSuite cipher_suites<2…2^16-2>; //支持的加密算法,如RSA
CompressionMethod compression_methods<1…2^8-1>; //支持的压缩算法
select (extensions_present) {
case false:
struct {};
case true:
Extension extensions<0…2^16-1>;
};
} ClientHello;

这里写图片描述

Server Hello

服务器端收到ClientHello消息后,如果有支持的TLS版本和相关算法,会回复客户端一个ServerHello消息,否则会关闭加密通信,所带信息如下:

struct {
ProtocolVersion server_version; //确定使用的SSL/TLS版本
Random random; //服务器端生成的随机数(暂命名server_hello_random),之后用于生成会话密钥
SessionID session_id;
CipherSuite cipher_suite; //确定使用的加密算法
CompressionMethod compression_method; //确实使用的压缩算法
select (extensions_present) {
case false:
struct {};
case true:
Extension extensions<0…2^16-1>;
};
} ServerHello;

ServerHello消息中确定使用的加密算法(cipher_suite)是从ClientHello消息中 cipher_suites 选择一个出来,如此次微信Web版抓包得到的消息:

Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)

  • ECDHE : 密钥交换算法,用于生成premaster_secret(用于生成会话密钥master secret),具体生成在Client Key Exchange Message节。
  • RSA : 签名算法,用户安全传输premaster_secret
  • AES_128 : 连接建立后的数据加密算法
  • GCM : 一种对称密钥加密操作的块密码模式

这里写图片描述

Server Certificate

这条消息将会在服务器发送ServerHello会立即发送给客户端,用于携带服务器证书信息。

struct {
ASN.1Cert certificate_list<0…2^24-1>; //服务器端证书链
}

这里写图片描述

Server Key Exchange Message(可选)

这条消息是用于会话密钥(premaster secret)生成的,首先这条消息不是必须的,只有在客户端与服务器端双方协商采用的加密算法是DHE_DSS、DHE_RSA、DH_anonServer Certificate消息中的服务器证书中的信息不足以生成premaster secret时服务器端才需要发送此消息。

struct {
select (KeyExchangeAlgorithm) {
case dh_anon:
ServerDHParams params;
case dhe_dss:
case dhe_rsa:
ServerDHParams params;
digitally-signed struct {
opaque client_random[32];
opaque server_random[32];
ServerDHParams params;
} signed_params;
case rsa:
case dh_dss:
case dh_rsa:
struct {} ;
/* message is omitted for rsa, dh_dss, and dh_rsa /
/
may be extended, e.g., for ECDH – see [TLSECC] */
};
} ServerKeyExchange;

这里写图片描述

Certificate Request(请求客户端证书,可选)

如果此次HTTPS连接是双向认证的话,服务器就可以通过此消息请求客户端证书以便进行身份验证。

struct {
ClientCertificateType certificate_types<1…2^8-1>;
SignatureAndHashAlgorithm
supported_signature_algorithms<2^16-1>; //服务器端可处理的签名算法列表
DistinguishedName certificate_authorities<0…2^16-1>;
} CertificateRequest;

微信Web版只需要服务器端认证所以不会发送此消息。

Server Hello Done

此消息由服务器端发送,表示服务器端已经完成了为支持密钥交换(生成premaster key)所做的事情,下面开始等待客户端为密钥交换所要发的消息。
客户端在收到此消息后,要验证服务器端证书是否合法,过期或不合法则浏览器会提示警告。
12306未导入它的证书前就会提示这个。
这里写图片描述

Client Certificate(客户端证书,可选)

客户端在收到Server Hello DoneCertificate Request后,表示服务器端需要验证客户端证书,这时客户端需要发送此Client Certificate消息给服务器端,即使没有客户端证书也要发个 certificate_list 列表为空的此消息,服务器端未收到或收到此消息后验证客户端证书,验证结果可酌情处理,如关闭加密通信或忽略此错误等。

struct {
ASN.1Cert certificate_list<0…2^24-1>; //客户端证书链
} Certificate;

Client Key Exchange Message

客户端收到Server Hello Done消息后就发送此消息用于将生成的premaster secret(用于生成会话密钥master secret)发送到服务器端。根据所采用的非对称加密的算法不同生成premaster secret的方式有所区别。

  • RSApremaster_secret是由客户端生成的随机数,用服务器证书中公钥加密后传输,服务器端采用私钥解密。
  • Diffie-Hellman: 对于Diffie-Hellman(简称DH)算法而言,双方通过Server Key Exchange MessageClient Key Exchange Message 交换两个数即可各自算出相同的加密密钥,用此当premaster_secret

Client Key Exchange Message 消息结构如下:

struct {
select (KeyExchangeAlgorithm) {
case rsa:
EncryptedPreMasterSecret; //premaster secret
case dhe_dss:
case dhe_rsa:
case dh_dss:
case dh_rsa:
case dh_anon:
ClientDiffieHellmanPublic;
} exchange_keys;
} ClientKeyExchange;

这里写图片描述

生成会话密钥(master secret)

服务器收到此消息后终于可以生成会话密钥了,客户端也会同步生成同样的会话密钥,我们要解答几个问题:

  1. 为何要生成master secret

RSA等非对称加密算法加密大量数据时的性能远小于AES等对称加密算法,所以前面所做的 Key Exchange 操作都是为了生成一个对称加密算法的密钥,以便提高通信性能。

  1. master secret的生成方法?

使用前面协商的如SHA_256哈希算法由三个随机数client_hello_random、server_hello_random、premaster_secret生成一个安全随机数,采用三个随机数是为了随机性更强

  1. 三个随机数都在不可靠网络上传输,如何保证master secret是保密的?

三个随机数中premaster_secret是保密的,所以master_secret也是保密的。

Certificate Verify(验证客户端证书有效性,可选)

如果是双向认证过程时,客户端会在Client Key Exchange Message之后发送此消息,携带有前面所发消息用客户端证书私钥所做的签名,服务器收到此信息可利用公钥验证,是典型的数字签名验证场景。

struct {
digitally-signed struct {
opaque handshake_messages[handshake_messages_length];
}
} CertificateVerify;

Change Cipher Spec(Client发送密钥改变通知)

客户端生成master secret之后即可发送密钥改变通知通知服务器,以后要使用对称密钥master secret来加密数据了!
这里写图片描述

Finished(Client握手结束通知)

客户端发送握手结束通知,同时会带上前面所发内容的签名到服务器端,保证前面通信数据的正确性。

Change Cipher Spec(Server发送密钥改变通知)

服务器端收到 Client Key Exchange Message 通知后即可通知客户端已生成master secret,后面的通信数据用此key加密。
这里写图片描述

Finished(Server握手结束通知)

服务器端发送握手结束通知,同时会带上前面所发内容的签名到客户端,保证前面通信数据的正确性。

好的,上面我们终于讲完了TLS握手协议。先放松一下。
在这里插入图片描述

TLS记录协议(TLS Record Protocol)

在整个过程中我们得到一个对称加密密钥可以用来加密数据,但怎么确保数据的完整性 这个问题还没有得到解答,让我们探究到底!

用于数据的完整性校验的Hash值存放在哪里?

TLS记录协议是对TLS握手协议更高级别的封装(它俩都属于TLS),提供了对数据的分片与安全传输功能。维基百科上TLS Record的数据格式:
在这里插入图片描述
不用细看,值得注意的值是MAC,没错,就是它。
每次传输的数据都会通过Hash算法算出一个MAC值附加在传输报文中,这个Mac值就用于数据的完整性校验。
是在数据被加密前就被计算出来,再由密钥同数据一块加密。为什么这么说?
直接上官方文档截图:

  1. 数据先被压缩
    在这里插入图片描述
  2. 再被加密,加密块中有MAC值。

原文:The encryption and MAC functions translate a TLSCompressed
structure into a TLSCiphertext.

在这里插入图片描述

MAC值到底是被哪个密钥加密的?

有很多文章说是通过TLS中的未对称加密算法(如RSA)来进行加解密的,由上个问题我们得知MAC与数据其实采用的同一个密钥,那么这个密钥是怎么生成的呢?
[MAC计算节](https://tools.ietf.org/html/rfc5246#section-6.3)中描述:

The master secret is expanded into a sequence of secure bytes, which
is then split to a client write MAC key, a server write MAC key, a
client write encryption key, and a server write encryption key.

TLS握手协议结束后最后得到的对称加密密钥即是master secretmaster secret又延伸出了client write encryption keyserver write encryption key
文章提到的write MAC key貌似与MAC生成有关?搜索一下

The MAC is generated as:

      MAC(MAC_write_key, seq_num +
                            TLSCompressed.type +
                            TLSCompressed.version +
                            TLSCompressed.length +
                            TLSCompressed.fragment);

答案得出:MAC值的生成与master secret强相关,与TLS采用的未对称加密算法无直接关系。
如果说的不对麻烦留言指点下~

文章开关问题解答

通过上面的分析我们可以得出其解决最开始三个问题的工作方式:

  1. 通信双方的身份验证
    通过验证双方签名证书。
  2. 通信数据的私密性
    通过使用非对称加密算法生成的对称加密密钥加密数据来保证数据的私密性。
  3. 通信数据的完整性
    数据在传输时会附带一个数据的信息摘要keyMAC,再将其加密,服务端收到消息后对其解密以检测数据有无篡改。

参考资料

TLS1.2协议官方文档

  • 11
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值