一、TLS1.3抓包分析——ClientHello
抓包使用的是WireShark2.6.7,抓包内容为
https://tls13.crypto.mozilla.org/
(Mozilla的TLS1.3测试页面),浏览器为chrome(需开启TLS1.3),这里我先给出抓包结果:
wireshark抓包
本次从握手的第一步开始分析,即ClientHello,下面是ClientHello的报文内容:
ClientHello
我们需要关注的是Secure Sockets Layer,即安全套接字层,下面是ClientHello所包含的内容:
ClientHello所包含的内容
Record Layer
,记录层
Content Type
:HandShake,表示内容类型为握手消息
Version
:TLS1.0(0x0301),版本号为1.0,为什么是1.0?之前看的draft好像固定1.2版本
后面是握手部分(Handshake)的内容,首先上图:
Handshake Protocol
Handshake Type
:ClientHello,表示握手消息类型,此处是ClientHello
Length
:557,即长度为557
Version
:TLS1.2(0x0303),表示版本号为1.2,在TLS1.3的草案当中规定此处必须置为0x0303,即TLS1.2,起到向后兼容的作用。1.3版本用来协商版本号的部分在扩展当中,而之前的版本就在此处进行。
Random
,随机数,是由安全随机数生成器生成的32个字节。
Session ID Length
:会话ID的长度。
Session ID
,会话ID,TLS 1.3之前的版本支持“会话恢复”功能,该功能已与1.3版本中的预共享密钥合并。为了兼容以前的版本,该字段必须是非空的,因此不提供TLS 1.3之前会话的客户端必须生成一个新的32字节值。该值不必是随机的,但应该是不可预测的,以避免实现固定在特定值,否则,必须将其设置为空。
Cipher Suites Length
,即下面Cipher Suites的长度
Cipher Suites
:密码套件,如图所示
Cipher Suites
该图中包含17个密码套件,每个加密套件一般包含密钥交换、签名算法、加密算法以及哈希算法。
Compression Methods
:压缩方法,TLS1.3中未涉及,所以固定长度为1,内容为空。
后面是Extensions扩展部分,扩展是TLS1.3才开始使用的,在之前的版本是没有的,所以扩展是1.3的显著特征,TLS 1.3 ClientHello消息始终包含扩展(最低限度为“supported_versions”,否则它们将被解释为TLS 1.2 ClientHello消息)。
后面是扩展部分的分析,每个扩展一般都包含类型(Type)、长度(Length)和数据(Data)三个部分。
Extensions
Reserved
:预留位置,为空。
Renegotiation info
:重新协商信息,如果是新发送的ClientHello一般是0,该扩展结构如图
Renegotiation info
Servername
:所请求的服务器名,结构如图
Servername
这里的服务器名为
tls13.crypto.mozilla.org
,是由Mozilla提供的用来测试TLS1.3的地址。
extended_master_secret
:内容为空,长度为0。
SessionTicket TLS
:会话Ticket,此处为空,长度为0。
signature_algorithms
:签名算法,内容如图所示
signature_algorithms
以第一个签名算法为例,
ecdsa_secp256r1_sha256
,使用sha256作为签名中的哈希,签名算法为ecdsa。
status_request
:协商OCSP,服务器可以通过在其CertificateRequest消息中发送空的“status_request”扩展来请求客户端使用其证书呈现OCSP响应。
signed_certificate_timestamp
:请求时间戳,可以简称为SCT,服务器将在CertificateEntry的扩展中携带时间戳。
application_layer_protocol_negotition
:ALPN协议,是TLS的扩展,允许在安全连接的基础上进行应用层协议的协商。ALPN协议的选择将会影响PSK Mode下早期数据的发送情况。
ALPN
channel_id
:此处长度为0,内容为空,频道id
ec_point_formats
:椭圆曲线点的格式,此处为uncompressed格式
Key_share
:共享密钥,结构如图
Key_share
此处包含两个KeyShareEntry,第一个是预留的空值,第二个是x25519曲线组,具体数据在KeyExchange字段中;每个KeyShareEntry都代表一组密钥交换参数。
psk_key_exchange_modes
:PSK密钥交换模式选择,如图
psk_key_exchange_modes
此处的PSK模式为(EC)DHE下的PSK,客户端和服务器必须提供KeyShare;如果是仅PSK模式,则服务器不需要提供KeyShare。
supported_versions
:客户端所支持的TLS版本,进行版本的协商,一般从优先级从高到低进行排列,此处优先选择1.3版本。
supported_groups
:客户端所支持的曲线组,如图
supported_groups
此处包含了三组曲线,分别是x25519、secp256r1和secp384r1,其中x25519在KeyShare部分已经进行了相关计算,并进行密钥协商。
Unknown type 27
:未知类型的数据,内容为02002。
Reserved
:保留位置,置为空。
pre_shared_key
:预共享密钥,如图
pre_shared_key
Identity
中包含的是客户端愿意进行协商的服务器身份列表,PSK binder值构建PSK与当前握手之间的绑定。
Obfuscated Ticket Age
,客户端的the age of a ticket(票据生存时间)是自收到NewSessionTicket消息以来的时间,客户不得尝试使用age大于ticket中的
ticket_lifetime
值的ticket。每个PskIdentity的
obfuscated_ticket_age
字段包含由age(
以毫秒为单位
)并添加ticket中包含的
ticket_age_add
值,模2^32形成的Ticket Age的模糊版本。
二、TLS1.3抓包分析——ServerHello
继续上次的报文分析,这次主要内容是TLS握手中的ServerHello消息。
SververHello
首先是记录层(Record Layer)内容,
Content Type
表示内容类型为握手(Handshake),
Version
表示版本为TLS1.2,接下来是长度(
Length
)。
后面是握手协议部分的内容,我将逐个解释(其实大部分都和ClientHello的内容类似):
Handshake Type
:ServerHello,表示握手消息类型,此处是ServerHello。
Length
:118,表示ServerHello的长度。
Version
:TLS1.2(0x0303),表示版本号为1.2。在TLS1.3的草案当中规定此处必须置为0x0303,即TLS1.2,起到向后兼容的作用。1.3版本用来协商版本号的部分在扩展当中,而之前的版本就在此处进行。
Random
,随机数,由服务器生成,必须独立于ClientHello.random的生成(即客户端和服务器的随机数是分别独立生成的)。
Session ID Length
:会话ID的长度。
Session ID
,会话ID,TLS 1.3之前的版本支持“会话恢复”功能,该功能已与1.3版本中的预共享密钥合并。为了兼容以前的版本,该字段必须是非空的,因此不提供TLS 1.3之前会话的客户端必须生成一个新的32字节值。该值不必是随机的,但应该是不可预测的,以避免实现固定在特定值。
Cipher Suites Length
,即下面Cipher Suites的长度。
Cipher Suites
:密码套件,此处为
TLS_AES_128_GCM_SHA256
,服务器从ClientHello.cipher_suites的列表中选择的单个密码套件。
Compression Methods
:压缩方法,TLS1.3中未涉及,所以固定长度为1,内容为空。
后面是扩展(Extensions)的内容,ServerHello的扩展只包括了两个内容,共享密钥和所支持的版本:
key_share
:共享密钥,如图
key_share
这里的类型跟长度不再解释,Key Share Entry中只包含了一个曲线组x25519(从ClientHello.key_share选择的结果),在Key Exchange中包含的就是相关参数。
supported_versions
:服务器所支持的TLS版本号,进行版本号的协商,如图:
supported_versions
此处是服务器在ClientHello.Versions上的选择,此处服务器选择了1.3版本。
当使用带有(EC)DHE密钥建立的PSK时,当前的ServerHello消息需包含 “pre_shared_key”和“key_share”扩展,其他扩展将在EncryptedExtensions消息中单独发送。
TLS 1.3具有嵌入在服务器随机值中的降级保护机制,响应ClientHello并协商TLS 1.2或更低版本的TLS时,服务器必须专门设置其Random值的最后8个字节。
如果协商TLS 1.2,TLS 1.3服务器必须将其Random值的最后八个字节设置为字节:
44 4F 57 4E 47 52 44 01
如果协商TLS 1.1或更低版本,TLS 1.3服务器必须和TLS 1.2服务器应该将其Random值的最后8个字节设置为字节:
44 4F 57 4E 47 52 44 00
客户端接收到ServerHello之后也将对随机数中的这8个字节进行检查,如果不匹配将会利用警报协议停止握手。
这里在ServerHello后面还有一点内容,即Change Cipher Spec,如图:
Change Cipher Spec
Change Cipher Spec
的目的是为了告知客户端,之后的消息将会加密传输;在1.2及之前的版本中都包含Change Cipher Spec,所以在TLS1.3中为了
保证兼容性
,也保留了这一部分。
三、TLS1.3抓包分析——EncryptedExtentions等
其实在最开始抓包的时候就发现了一个问题,就是在ChangeCipherSpec消息之后,没有加密扩展、证书,甚至Finished消息都没有。在握手过程中,Finished消息是一定存在的,所以说明用Wireshark抓的包存在问题,之前提到过,ChangeCipherSpec之后的消息都是进行加密了的,所以可能是因为Wireshark没有对后续的消息进行解密,所以只是显示了ApplicationData,即加密传输的数据。
wireshark抓包1
那么要想利用wireshark对其进行分析,就要想办法得到密钥,对加密的消息进行解密,这里的解决方法参照
https://jingyan.baidu.com/article/20b68a88b2af7f796cec62b3.html
。
简要步骤:
1.创建一个log文件,因为Firefox和Chrome浏览器都支持用log文件的方式记录下用来加密TLS数据包对称会话秘钥的,所以创建ssl.log来保存会话密钥。
2.配置环境变量。右键点击我的电脑->属性->高级系统设置->高级->环境变量->系统变量
环境变量1
然后新建一个系统环境变量,变量名是SSLKEYLOGFILE,变量值就是你的log文件的位置。
环境变量2
3.在Wireshark中进行配置。编辑->首选项->协议Protocols->SSL,在(pre)-Master-Secret log filename一栏中添加刚才的log文件位置。
Wireshark配置
然后再进行抓包,抓包结果如图:
抓包结果
可以看到之前的
Application Data
被解析为
EncryptedExtentions、Certificate、Certificate verrify、Finished
,下面将对这几个消息进行逐个分析。
解析后的消息
Encrypted Extentions加密扩展
Encrypted Extentions
加密扩展中包含两个扩展内容——
supported_groups
和
server_name
。
Type
、
Length
依旧表示类型和长度,不再进行单独解释。
supported_groups
包含的是服务器所支持的曲线组,这里有x25519、secp256r1、secp384r1。
server_name
表示服务器名,此处加密扩展是服务器发给客户端的,所以置为空。
Certificate
Certificate1
Certificate Request Context Length
,在此处置为空,即长度为0。
Certificate Request
一般是在加密扩展消息之后服务器(可选)进行发送的,服务器用它来请求客户端发送证书,如果服务器发送了Certificate Request,客户端一般需要在后面发送自己的Certificate,并在Certificate消息中包含Certificate Request Context来进行响应;所以服务器发送的证书中,Certificate Request Context为空,长度为0。
Certificates
,证书(CertificateEntry)序列,每个CertificateEntry包含一个证书和一组扩展。
signedCertificate
:
version
,版本为v3;
serialNumber
,序列号。
signature
:
Algorithm Id
,签名算法ID,这里表示sha256WithRSAEncryption。
issuer
,证书颁发者,用
X.509 DN
表示,DN是由RDN构成的序列,RDN用“属性类型=属性值”的形式表示。
CountryName
,国家,此处为US。
OrganizationName
,机构名,此处为Let’s Encrypted。
commonName
,通用名称,此处为Let’s Encrypted Authority X3。
Certificate2
validity
,表示证书的合法性,包含证书有效期的起止时间。
subject
,证书的主体,也用
X.509 DN
表示,即RDN序列。
commonName
,通用名称,此处为tls13.crypto.mozilla.org,即所颁发证书的对象。
subjectPublicKeyInfo
,证书主体公钥信息。
Algorithm
,公钥算法,这里用的是RSA。
subjectPublicKey
包含的就是具体的公钥,包括
modulus
(系数)和
Exponent
(指数)。
Certificate3
extentions
,扩展,这里有9个扩展,分别是
keyUsage
、
extKeyUsage
、
basicConstraints
、
subjectKeyIdentifier
、
authorityKeyIdentifier
、
authorityInfoAccessSyntax
、
subjectAltName
、
certificatePolicies
、
SignedCertificateTimestampList
。
keyUsage
keyUsage
,表示证书的公钥可以完成的功能或服务,这里包含digitalSignature和keyEncipherment。
extensions
extKeyUsage
,表示Extended Key Usage,包含一系列的KeyPurposeID,每一个都表示一种用途,这里包括serverAuth和clientAuth。
basicConstraints
,基本约束扩展,标识证书的主体是否为CA以及包含有效证书路径的最大深度。
subjectKeyIdentifier
,主体密钥标识符,用来识别包含特定密钥的证书。
authorityKeyIdentifier
,**密钥标识符,用来识别证书所用私钥对应的公钥。
extensions
authorityInfoAccessSyntax
,序列中的每个条目都描述了扩展所在的证书的颁发者提供的附加信息的格式和位置。信息的类型和格式由accessMethod字段指定;accessLocation字段指定信息的位置。
subjectAltName
,表示Subject Alternative Name,主体可选名,可使身份与证书主体绑定,此处只给出了一个GeneralName。
certificatePolicies扩展
certificatePolicies
,证书策略扩展包含一个或多个策略信息术语的序列,每个术语由对象标识符(object identifier,OID)和可选限定符(optional qualifiers)组成。
SignedCertificateTimestampList
SignedCertificateTimestampList
,表示证书时间戳序列,包含时间戳(Timestamp)、签名算法(Signature Algorithm)、签名(Signature)以及其他字段。
从
signature
到刚才的
extensions
都是
signedCertificate
中的内容。
Certificate4
algorithmIdentifier
,表示算法标识符,包含Algorithm ID,对应于特定算法,此处为sha256WithRSA。
Padding
,填充内容,此处为空。
另外一个证书的内容和上述内容类似,不再进行详细叙述,因为证书的内容不是研究的重点,所以叙述比较简单,具体看rfc5280对X.509证书的定义
https://tools.ietf.org/html/rfc5280#section-4.1.2.9
。
Certificate Verify
Certificate Verify and Finished
Signature Algorithm
,签名算法,此处为rsa_pss_rsae_sha256。
Signature
,签名内容。
Finished
Finished
消息是身份验证阶段的最后一条消息,
Verify Data
是通过HMAC计算得来的,包含finished_key和握手消息的hash。
verify_data =HMAC(finished_key,Transcript-Hash(Handshake Context,Certificate
, CertificateVerify
))
四、TLS1.3抓包分析(4)——NewSessionTicket
上次对客户端的认证阶段进行了分析,本次继续上次的内容往后进行分析。
本次内容
先看Client响应的
Change Cipher Spec
和
Finished
消息,当服务器在前面发送了
Certificate Request
时,客户端往往也要发送自己的证书Certificate以及Certificate Verrify。
Change Cipher Spec & Finished From Client
从图中就可以看出,消息格式和之前服务器发送的是一样的,所以不再进行分析。
New Session Ticket
在服务器收到客户端Finished消息后的任何时间,它都可以发送NewSessionTicket消息。
New Session Ticket
Type
、
Version
、
Length
表示类型、版本、长度。
Session Ticket Lifttime Hint
,表示Ticket的剩余有效时间,此处为172800秒。
Session Ticket Age Add
,生成的随机32位值。ClientHello中的
obfuscated_ticket_age
字段需要将Ticket Age添加上Ticket Age Add,并模2^32得到模糊值(即Obfuscated Ticket Age)。
Session Ticket Nonce
,每个nonce值在此连接上发送的所有Ticket中都应是唯一的。
Session Ticket
,用来标识特定的PSK。
Extension
,Ticket的扩展值,当前为NewSessionTicket定义的唯一扩展名为
early_data
,表示该票据可用于发送0-RTT数据,包含值
Maximum Early Data Size
,表示允许客户端发送的最大0-RTT数据量(以字节为单位),接收超过max_early_data_size字节的0-RTT数据的服务器应该使用
unexpected_message
警报终止连接。
作者:汪哈哈zzz
链接:https://www.jianshu.com/p/f74e751a9603
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。