本文内容来自《Traffic Analysis of an SSL/TLS Session》的阅读笔记,原文见此处

TLS 全称为 Transport Layer Security,它本身也分为了 Lower 和 Higher 两层协议。

Lower Layer

Lower Layer 协议在 TCP 协议之上,提供面向连接的可靠传输,在这一层的协议主要是记录协议(TLS Record Protocol)。 记录协议首先把上层协议传来的数据分成小于2^14字节的数据块,如果设置了压缩选项,则第二步为压缩数据,然后在数据块的末尾增加 MAC(Message Authentication Code),第三步将数据块加密,最后增加记录头。该过程如下所示。

each block is packed into a structure that does not preserve client message boundaries, meaning that mulitiple message of the same type maybe coalesced into a single structure

-----------+
  data   --+--------------> 1. Fragment data
-----------+
                            +------------------------+
                            |                        |
                            |                        |
                            +------------------------+
                            2. Compress data (generally no compression applied)
                            +------------------------+----+
                            |                        |MAC | Add a Message Authentication Code
                            |                        |    |
                            +------------------------+----+
                            3. Encrypt data
                            +-----------------------------+
                            |ciphertext                   |
                            |                             |
                            +-----------------------------+
                            4. Add header
                       +----+-----------------------------+
            TLS Record |    |ciphertext                   | Add a TLS Record header
              header   |    |                             |
                       +----+-----------------------------+

Higher Layer

主要有四种协议。

  • 握手协议(Handshake Protocol)建立通信。
  • 密钥交换协议(ChangeCipherSpec Protocol)让之前协商好的协议生效,此时通信加密。
  • 警告协议(Alter Protocol)通信出现异常时使用,提示用户潜在的安全问题。
  • 程序数据协议(Application Data Protocol)数据通信。

握手的过程如下所示。

               TLS Handshake

               +-----+                              +-----+
               |     |                              |     |
               |     |        ClientHello           |     |
               |     o----------------------------> |     |
               |     |                              |     |
       CLIENT  |     |        ServerHello           |     |  SERVER
               |     |       [Certificate]          |     |
               |     |    [ServerKeyExchange]       |     |
               |     |    [CertificateRequest]      |     |
               |     |      ServerHelloDone         |     |
               |     | <----------------------------o     |
               |     |                              |     |
               |     |       [Certificate]          |     |
               |     |     ClientKeyExchange        |     |
               |     |    [CertificateVerify]       |     |
               |     |   ** ChangeCipherSpec **     |     |
               |     |         Finished             |     |
               |     o----------------------------> |     |
               |     |                              |     |
               |     |   ** ChangeCipherSpec **     |     |
               |     |         Finished             |     |
               |     | <----------------------------o     |
               |     |                              |     |
               +-----+                              +-----+
 Optional messages
 --------------------------------------------------------------------------------------------
 Certificate (server)     包含秘钥交换的算法(匿名通信除外)
 ServerKeyExchange        使用 Diffie-Hellman 秘钥交换算法时需要
 CertificateRequest       如果设置了 Client authentication
 Certificate (client)     客户端回复服务端发送的 CertificateRequest
 CertificateVerify        如果客户端发送了 Certificate message

Record Protocol 的格式

记录协议的记录头非常简单,占用5个字节。

         record type (1 byte)
        /
       /    version (1 byte major, 1 byte minor)
      /    /
     /    /         length (2 bytes)
    /    /         /
 +----+----+----+----+----+
 |    |    |    |    |    |
 |    |    |    |    |    | TLS Record header
 +----+----+----+----+----+

 Record Type Values       dec      hex
 -------------------------------------
 CHANGE_CIPHER_SPEC        20     0x14
 ALERT                     21     0x15
 HANDSHAKE                 22     0x16  <- 22 和 23 比较常见
 APPLICATION_DATA          23     0x17  <-

 Version Values            dec     hex
 -------------------------------------
 SSL 3.0                   3,0  0x0300
 TLS 1.0                   3,1  0x0301
 TLS 1.1                   3,2  0x0302
 TLS 1.2                   3,3  0x0303

Handshake Protocol 格式

握手协议的类型比较复杂,基本类型的有10种,这还不包括 TLS 扩展协议。类型占1字节,消息长度占3字节,后面是消息的内容。

                           |
                           |
                           |
         Record Layer      |  Handshake Layer
                           |                                  |
                           |                                  |  ...more messages
  +----+----+----+----+----+----+----+----+----+------ - - - -+--
  | 22 |    |    |    |    |    |    |    |    |              |
  |0x16|    |    |    |    |    |    |    |    |message       |
  +----+----+----+----+----+----+----+----+----+------ - - - -+--
    /               /      | \    \----\-----\                |
   /               /       |  \         \
  type: 22        /        |   \         handshake message length  + type = 占用4字节
                 /              type
                /
           length: arbitrary (up to 16k)


   Handshake Type Values    dec      hex
   -------------------------------------
   HELLO_REQUEST              0     0x00
   CLIENT_HELLO               1     0x01
   SERVER_HELLO               2     0x02
   CERTIFICATE               11     0x0b
   SERVER_KEY_EXCHANGE       12     0x0c
   CERTIFICATE_REQUEST       13     0x0d
   SERVER_DONE               14     0x0e
   CERTIFICATE_VERIFY        15     0x0f
   CLIENT_KEY_EXCHANGE       16     0x10
   FINISHED                  20     0x14

HelloRequest 这是由服务器主动发起的握手,这种情况不常发生,主要是用在一个 session 已经持续了很长时间,服务器为了降低安全隐患,重新与客户端建立新的连接。

     |
     |
     |
     |  Handshake Layer
     |
     |
- ---+----+----+----+----+
     |    |    |    |    |
   4 |  0 |  0 |  0 |  0 |
- ---+----+----+----+----+
  /  |  \    \---------\
 /       \        \
record    \    length: 0
length     \
            type: 0

ClientHello 各个字段的含义很清楚,其中 session id 是指 client 在已经建立的 TLS 连接上重新建立时,可以包含这一个 session id 发给服务器。

     |
     |
     |
     |  Handshake Layer
     |
     |
- ---+----+----+----+----+----+----+------+----+----------+--------+-----------+----------+
     |  1 |    |    |    |    |    |32-bit|    |max 32-bit| Cipher |Compression|Extensions|
     |0x01|    |    |    |  3 |  1 |random|    |session Id| Suites |  methods  |          |
- ---+----+----+----+----+----+----+------+----+----------+--------+-----------+----------+
  /  |  \    \---------\    \----\             \       \
 /       \        \            \                \   SessionId
record    \     length        SSL/TLS            \
length     \                  version         SessionId
            type: 1       (TLS 1.0 here)       length

CipherSuites

+----+----+----+----+----+----+
|    |    |    |    |    |    |
|    |    |    |    |    |    |
+----+----+----+----+----+----+
  \-----\   \-----\    \----\
     \         \          \
      length    cipher Id  cipherId     <--加密算法用 id 表示

Compression methods (no practical implementation uses compression)

+----+----+----+
|    |    |    |
|  0 |  1 |  0 |
+----+----+----+
  \-----\    \
     \        \
 length: 1    cmp Id: 0

Extensions

+----+----+----+----+----+----+----- - -
|    |    |    |    |    |    |
|    |    |    |    |    |    |...extension data
+----+----+----+----+----+----+----- - -
  \-----\   \-----\    \----\
     \         \          \
    length    Extension  Extension data
                 Id          length

ServerHello 与 ClientHello 不同的是,它只包含一个 CipherSuite 和 一个 Compression,这是因为服务器选定要使用的加密算法和压缩算法。

     |
     |
     |
     |  Handshake Layer
     |
     |
- ---+----+----+----+----+----+----+----------+----+----------+----+----+----+----------+
     |  2 |    |    |    |    |    |  32byte  |    |max 32byte|    |    |    |Extensions|
     |0x02|    |    |    |  3 |  1 |  random  |    |session Id|    |    |    |          |
- ---+----+----+----+----+----+----+----------+----+----------+--------------+----------+
  /  |  \    \---------\    \----\               \       \       \----\    \
 /       \        \            \                  \   SessionId      \  Compression
record    \     length        SSL/TLS              \ (if length > 0)  \   method
length     \                  version           SessionId              \
            type: 2       (TLS 1.0 here)         length            CipherSuite

Certificate 证书链。

     |
     |
     |
     |  Handshake Layer
     |
     |
- ---+----+----+----+----+----+----+----+----+----+----+-----------+---- - -
     | 11 |    |    |    |    |    |    |    |    |    |           |
     |0x0b|    |    |    |    |    |    |    |    |    |certificate| ...more certificate
- ---+----+----+----+----+----+----+----+----+----+----+-----------+---- - -
  /  |  \    \---------\    \---------\    \---------\
 /       \        \              \              \
record    \     length      Certificate    Certificate
length     \                   chain         length
            type: 11           length

ServerKeyExchange 由客户端接收。客户端需要服务端提供这个参数,用于建立对称加密。这是一个可选的参数,并不是所有的秘钥交换算法都需要提供这个参数。 参数的格式根据 CipherSuite 的不同而不同。

     |
     |
     |
     |  Handshake Layer
     |
     |
- ---+----+----+----+----+----------------+
     | 12 |    |    |    |   algorithm    |
     |0x0c|    |    |    |   parameters   |
- ---+----+----+----+----+----------------+
  /  |  \    \---------\
 /       \        \
record    \     length
length     \
            type: 12

CertificateRequest 服务器要求客户端也提供证书。这种在 web 服务器中并不常见。 CertificateRequest 消息告诉客户端,服务器接收哪些 certificate 类型,以及信任哪些 CA。

     |
     |
     |
     |  Handshake Layer
     |
     |
- ---+----+----+----+----+----+----+---- - - --+----+----+----+----+-----------+-- -
     | 13 |    |    |    |    |    |           |    |    |    |    |    C.A.   |
     |0x0d|    |    |    |    |    |           |    |    |    |    |unique name|
- ---+----+----+----+----+----+----+---- - - --+----+----+----+----+-----------+-- -
  /  |  \    \---------\    \    \                \----\   \-----\
 /       \        \          \ Certificate           \        \
record    \     length        \ Type 1 Id        Certificate   \
length     \             Certificate         Authorities length \
            type: 13     Types length                         Certificate Authority
                                                                      length

ServerHelloDone 非常简单的一条消息。

     |
     |
     |
     |  Handshake Layer
     |
     |
- ---+----+----+----+----+
     | 14 |    |    |    |
   4 |0x0e|  0 |  0 |  0 |
- ---+----+----+----+----+
  /  |  \    \---------\
 /       \        \
record    \     length: 0
length     \
            type: 14

ClientKeyExchange 它提供给服务器一个用于生成对称加密的参数。至此,客户端和服务器都拥有了相同的2份参数。

     |
     |
     |
     |  Handshake Layer
     |
     |
- ---+----+----+----+----+----------------+
     | 16 |    |    |    |   algorithm    |
     |0x10|    |    |    |   parameters   |
- ---+----+----+----+----+----------------+
  /  |  \    \---------\
 /       \        \
record    \     length
length     \
            type: 16

CertificateVerify

     |
     |
     |
     |  Handshake Layer
     |
     |
- ---+----+----+----+----+----------+
     | 15 |    |    |    |  signed  |
     |0x0f|    |    |    |   hash   |
- ---+----+----+----+----+----------+
  /  |  \    \---------\
 /       \        \
record    \     length
length     \
            type: 15

Finished 这个消息发送时,已经是被加密的了。 因为 negotiation 已经结束,ChangeCipherSpec 消息已经发送并激活双方的加密通信。 (ChangeCipherSpec 协议并不属于握手协议的一部分,因此并没有在这一节中介绍)。 Finished 消息中包含的 hash 值与CertificateVerify中的并不同,因为它包含了更多的握手信息产生的摘要。

     |
     |
     |
     |  Handshake Layer
     |
     |
- ---+----+----+----+----+----------+
     | 20 |    |    |    |  signed  |  <--- hash 之后还有 master secret 
     |0x14|    |    |    |   hash   |
- ---+----+----+----+----+----------+
  /  |  \    \---------\
 /       \        \
record    \     length
length     \
            type: 20

ChangeCipherSpec Protocol 格式

按照逻辑理解,ChangeCipherSpec 应该是属于握手协议的一部分,但是却被单独列出来,这是因为记录协议的封装导致的。 记录协议的记录块是一整块被加密的,一个记录块小于等于 2^16 字节。假如 ChangeCipherSpec 所在块中有用户数据,那么这个数据 应该被加密,但是事实上,无法对记录块中的部分数据进行加密。所以单独列出。

                           |
                           |
                           |
         Record Layer      |  ChangeCipherSpec Layer
                           |
                           |
  +----+----+----+----+----+----+
  | 20 |    |    |    |    |    |
  |0x14|    |    |  0 |  1 |  1 |
  +----+----+----+----+----+----+
    /               /      |
   /               /       |
  type: 20        /        |
                 /
                /
           length: 1

Alert Protocol 格式

警告协议报告通信过程中出现的异常。消息格式非常简单。

                           |
                           |
                           |
         Record Layer      |  Alert Layer
                           |
                           |
  +----+----+----+----+----+----+----+
  | 21 |    |    |    |    |    |    |
  |0x15|    |    |  0 |  2 |    |    |
  +----+----+----+----+----+----+----+
    /               /      |
   /               /       |
  type: 21        /        |
                 /
                /
           length: 2

  Alert severity               dec     hex
  ----------------------------------------
  WARNING                        1    0x01
  FATAL                          2    0x02

  TLS 1.0 Alert descriptions   dec     hex
  ----------------------------------------

  CLOSE_NOTIFY                   0    0x00
  UNEXPECTED_MESSAGE            10    0x0A
  BAD_RECORD_MAC                20    0x14
  DECRYPTION_FAILED             21    0x15
  RECORD_OVERFLOW               22    0x16
  DECOMPRESSION_FAILURE         30    0x1E
  HANDSHAKE_FAILURE             40    0x28
  NO_CERTIFICATE                41    0x29
  BAD_CERTIFICATE               42    0x2A
  UNSUPPORTED_CERTIFICATE       43    0x2B
  CERTIFICATE_REVOKED           44    0x2C
  CERTIFICATE_EXPIRED           45    0x2D
  CERTIFICATE_UNKNOWN           46    0x2E
  ILLEGAL_PARAMETER             47    0x2F
  UNKNOWN_CA                    48    0x30
  ACCESS_DENIED                 49    0x31
  DECODE_ERROR                  50    0x32
  DECRYPT_ERROR                 51    0x33
  EXPORT_RESTRICTION            60    0x3C
  PROTOCOL_VERSION              70    0x46
  INSUFFICIENT_SECURITY         71    0x47
  INTERNAL_ERROR                80    0x50
  USER_CANCELLED                90    0x5A
  NO_RENEGOTIATION             100    0x64

ApplicationData Protocol 格式

                           |
                           |
                           |
         Record Layer      |  ApplicationData Layer (encrypted)
                           |
                           |
  +----+----+----+----+----+----+----+--- - - - - - - --+---------+
  | 23 |    |    |    |       length-delimited data     |         |
  |0x17|    |    |    |    |    |    |                  |   MAC   |
  +----+----+----+----+----+----+----+--- - - - - - - --+---------+
    /               /      |
   /               /       |
  type: 23        /        |
                 /
                /
           length: arbitrary (up to 16k)