Https其实就是在TLS之上的http协议,所以各种头信息以及数据格式和http其实都一样,主要区别就在TLS,下面我们来看看TLS是如何工作的(建议用电脑查看图片)。
TLS 握手
访问百度,并用wireshark 抓包。看一下具体的流程:
下面是几个重要过程的数据包
Client Hello
- 客户端支持的TLS协议版本,这里会有一个list,目前主流的是TLS1.2。
- 一个随机数,我们记为CR,具体的作用是用来生成对话密钥,我们稍后会用到。
- 支持的加密方法套件。
- 支持的压缩方法。
- 扩展信息。扩展信息会有非常多,类似时间戳,域名等等信息,具体的可以参看RFC文档。
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 196
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 192
Version: TLS 1.2 (0x0303)
Random
GMT Unix Time: Sep 17, 2001 11:39:28.000000000 HKT
Random Bytes: bc19ae324b40e089aa93497dc631b11e9ac623631eba8c2e...
/*
Session Id。跟SSO的cookie的概念有点类似,就是当你这次握手成功之后,
下次直接带上这个session Id,如果服务端认为合法,那么就不用再进行握手,
直接可以开始用之前已经商量好的对称加密密钥开始通信了。
*/
Session ID Length: 0
Cipher Suites Length: 28
Cipher Suites (14 suites)
Compression Methods Length: 1
Compression Methods (1 method)
Extensions Length: 123
Extension: Unknown 31354
Extension: renegotiation_info
Extension: server_name
Type: server_name (0x0000)
Length: 18
Server Name Indication extension
Server Name list length: 16
Server Name Type: host_name (0)
Server Name length: 13
Server Name: www.baidu.com
Extension: Extended Master Secret
Extension: SessionTicket TLS
Extension: signature_algorithms
/*
服务端设置了`status_request`的应答标志位,答应客户端会直接返回服务端证 书的OCSP校验结果。
*/
Extension: status_request
Type: status_request (0x0005)
Length: 5
Certificate Status Type: OCSP (1)
Responder ID list Length: 0
Request Extensions Length: 0
Extension: signed_certificate_timestamp
Extension: Application Layer Protocol Negotiation
Extension: channel_id
Extension: ec_point_formats
Extension: elliptic_curves
Extension: Unknown 27242
Server Hello
- 确认TLS协议的版本,如果客户端的协议服务端不支持的话,服务端会选择关闭这个连接。
- 从客户端支持的加密方法中,选择一个加密方式,并告知客户端。
- 生成一个随机数,我们记为SR,后续我们会结合CR生成对话密钥,稍后会用到。
- 从客户端支持的压缩算法中,选择一个压缩算法。
TLSv1.2 Record Layer: Handshake Protocol: Server Hello
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 63
Handshake Protocol: Server Hello
Handshake Type: Server Hello (2)
Length: 59
Version: TLS 1.2 (0x0303)
Random
GMT Unix Time: Jul 13, 2017 17:36:48.000000000 HKT
Random Bytes: 604b936787061df57c30ab5a30ab5e72f960975f8c91fc81...
Session ID Length: 0
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Compression Method: null (0)
Extensions Length: 19
Extension: SessionTicket TLS
Type: SessionTicket TLS (0x0023)
Length: 0
Data (0 bytes)
Extension: Application Layer Protocol Negotiation
Type: Application Layer Protocol Negotiation (0x0010)
Length: 11
ALPN Extension Length: 9
ALPN Protocol
ALPN string length: 8
ALPN Next Protocol: http/1.1
Certificate
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Certificate
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 2894
Handshake Protocol: Certificate
Handshake Type: Certificate (11)
Length: 2890
Certificates Length: 2887
Certificates (2887 bytes)
Certificate Length: 1748
Certificate: 308206d0308205b8a003020102020c18da1aafdb3d41309f... (id-at-commonName=baidu.com,id-at-organizationName=BeiJing Baidu Netcom Science Technology ,id-at-organizationalUnitName=service operation department.,id-at-localityName=beij
signedCertificate
algorithmIdentifier (sha256WithRSAEncryption)
Padding: 0
encrypted: 4b73ec2dd7ecca08f39dbd9554b100225948299248108d31...
Certificate Length: 1133
Certificate: 3082046930820351a003020102020b040000000001444ef0... (id-at-commonName=GlobalSign Organization Validation CA - SHA256,id-at-organizationName=GlobalSign nv-sa,id-at-countryName=BE)
signedCertificate
algorithmIdentifier (sha256WithRSAEncryption)
Padding: 0
encrypted: 462aee5ebdae0160373111867174b64649c81016fe2f6223...
Server Key Exchange
这一步也是可选的,取决于双方的加密方法,这里就不得不提到TLS的两种密钥协商方式:
- TLS_RSA_XXXX。这类算法里面,RSA的作用是Key Transmission
,也就是说对称加密的密钥是由客户端生成,然后通过证书里面的公钥加密发送给服务端。如果采用的是RSA算法,那么这一步就不需要了。 - TLS_DHE_XXXX。这类算法里面,使用DH算法进行密钥协商,DH的作用就是Key Exchange,密钥是由客户端和服务端共同生成的。
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Server Key Exchange
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 333
Handshake Protocol: Server Key Exchange
Handshake Type: Server Key Exchange (12)
Length: 329
EC Diffie-Hellman Server Params
Curve Type: named_curve (0x03)
Named Curve: secp256r1 (0x0017)
Pubkey Length: 65
Pubkey: 04fae2fd600115cd62361d34ed6c6d9b7bda6c9e6517ad1f...
Signature Hash Algorithm: 0x0401
Signature Hash Algorithm Hash: SHA256 (4)
Signature Hash Algorithm Signature: RSA (1)
Signature Length: 256
Signature: a0ba11e63a9c2155f0e895d0849518536951ca93039ab7d4...
科普一下DH
DH用于解决对称加密中密钥传递的安全问题。 DH加密算法为非对称加密算法,所谓非对称即加密与解密使用的密钥不同。一个公开,称为公钥;一个保密,称为私钥。
B必须使用A的公钥作为参数来构建自己的密钥对,否则无法确保B 和A使用同一个私钥。
虽然A 和B双方使用了不同的密钥来构建本地密钥,但得到的密钥是一致的。这里的说明可以更好的理解为什么密钥是一致的。
Server Hello Done
告诉客户端,整个Server Hello 阶段已经结束,等待客户端回复。
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Server Hello Done
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 4
Handshake Protocol: Server Hello Done
Handshake Type: Server Hello Done (14)
Length: 0
Client key exchange ,Change Cipher Spec
这里把DH算法的客户端公钥发送给服务端,这条消息必须在Client Certificate(如果有的话)之后立即发送。
这里的Key Exchange交换的就是pre-master key,有了pre-master key和我们之前生成两个随机数CR和SR就能够计算出我们的对称加密的密钥了,这里总共分为两种情况:
如果采用的是RSA算法,这里就是一个客户端产生的48 byte的随机数,用服务端的公钥加密之后发送。这里需要用公钥加密的原因在于,前两个随机数都是明文传输的,而采用RSA方式传输密钥,如果三个随机数都是明文,那么就可以计算出对称加密的密文了,所以这里一定是要加密传输。
如果采用的是DH算法及各种变种算法(如:ECDHE),这里发送的就是客户端公钥。这个消息不用公钥加密,原因在于DH算法本身的作用就是在不安全的通信通道交换一个安全的加密密钥。
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Client Key Exchange
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 70
Handshake Protocol: Client Key Exchange
Handshake Type: Client Key Exchange (16)
Length: 66
EC Diffie-Hellman Client Params
Pubkey Length: 65
Pubkey: 046ac098d21b903b341e16a49d8ec2cbfde65e91ae199fa4...
TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
Content Type: Change Cipher Spec (20)
Version: TLS 1.2 (0x0303)
Length: 1
Change Cipher Spec Message
TLSv1.2 Record Layer: Handshake Protocol: Multiple Handshake Messages
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 40
Handshake Protocol: Hello Request
Handshake Type: Hello Request (0)
Length: 0
Handshake Protocol: Hello Request
Handshake Type: Hello Request (0)
Length: 0
整个流程可以简单概括为:
- 通过TLS握手后,客户端拿到服务端的公钥构建密钥对,并把客户端的公钥发送给服务端。这时候的公钥也就是pre-master secret。
- C和S 通过使用各自pre-mastersecret以及结合CR + SR,生成对称密钥。
- 随后的通讯使用对称密钥加密。
服务器与浏览器的Https握手
服务器与浏览器在传输数据之前,会进行一次握手,握手过程中会确定双方加密传输数据的密码信息。握手及数据传输过程遵循TLS/SSL协议。
服务器与浏览器握手的意义在于:确定通信信道的安全,通过握手协商出双方传输数据的密码,只要保证了通信信道的安全,双方就可以用对称密码加密通信内容,因为对称加密的速度要比非对称加密快得多。
TLS/SSL中使用了非对称加密,对称加密以及HASH算法。握手过程的简单描述如下:
浏览器将自己支持的一套加密规则发送给网站。
网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。
-
获得网站证书之后浏览器要做以下工作:
验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。
如果证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串随机数的密码,并用证书中提供的公钥加密。
使用约定好的HASH计算握手消息,并使用生成的随机数对消息进行加密,最后将之前生成的所有信息发送给网站。
-
网站接收浏览器发来的数据之后要做以下的操作:
使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手消息,并验证HASH是否与浏览器发来的一致。
使用密码加密一段握手消息,发送给浏览器。
浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。
这里浏览器与网站互相发送加密的握手消息并验证,目的是为了保证双方都获得了一致的密码,并且可以正常的加密解密数据,为后续真正数据的传输做一次测试。
其中非对称加密算法用于在握手过程中加密生成的密码,对称加密算法用于对真正传输的数据进行加密,而HASH算法用于验证数据的完整性。由于浏览器生成的密码是整个数据加密的关键,因此在传输的时候使用了非对称加密算法对其加密。非对称加密算法会生成公钥和私钥,公钥只能用于加密数据,因此可以随意传输,而网站的私钥用于对数据进行解密,所以网站都会非常小心的保管自己的私钥,防止泄漏。
扩展阅读
What's the purpose of Server Key Exchange when using Ephemeral Diffie-Hellman?
SSL Introduction with Sample Transaction and Packet Exchange
Differences between the terms “pre-master secret”, “master secret”, “private key”, and “shared secret”?
TLS, Pre-Master Secrets and Master Secrets
SSL握手协议
PlantUML Code
记下UML图生成代码,方便以后修改。
@startuml
actor Client
actor Server
Client -> Server : 1) Client Hello
note left
支持的TLS协议版本 ,支持的加密方法,支持的压缩方法 ,随机数CR,
扩展信息里面包括:请求域名,服务器证书的校验结果,检验方式.
end note
Server -> Client : 2) Server Hello
note right
确认TLS协议版本,确定加密方法,随机数SR,确认压缩算法
end note
Server -> Client : 3) Server Certificate,Server Key Exchange(optional),Client Certificate Request(optional)
note right
1)发送证书链给客户端验证
2)发送Server的Pre Master Secret给客户端
3)要求验证客户端的证书
end note
Server -> Client : 4) Server Hello Done
note right
告诉客户端,整个Server Hello
阶段已经结束,等待客户端回复。
end note
Client -> Server : 5) Client Certificate (optional)
note left
只有在服务端要求验证客户端证书(上面的第三步),客户端发
才送证书.这是客户端在Server Hello Done之后发送的第
一条数据。
end note
Client -> Server : 6) Client Key Exchange
note left
此消息必须在Client Certificate(如果有的话)之后立即发送。
把Client的Pre Master Secret发送给Server。用于结合之前生成
两个随机数CR和SR生成对称加密密钥。
end note
Client -> Server : 7) Change Cipher Spec
note left
告诉服务端:客户端之后通信就开始使用
之前约定好的加密方式来加密传输了
end note
Client -> Server : 8) Encrypted Handshake Message
note left
这一步的作用是把之前握手的所有消息,用加密套件里的hash算法计算出一个值,然后用
刚刚协商好的对称加密的密钥进行加密,发送给服务端,即能验证之前发送的消息有没有
被篡改,又能验证下服务端计算的密钥对不对,如果计算不对就解不出明文。
end note
Server -> Client : 9) Change Cipher Spec
note right
告诉客户端:服务端之后通信就开始使用之前约定好
的加密方式来加密传输了
end note
Server -> Client : 10 )Encrypted Handshake Message
@enduml