SSL Handshake Protocol

Wed, Sep 9, 2020 6-minute read

Là giao thức cho phép 2 bên thỏa thuận các tham số kết nối, thực hiện xác thực. Phase này thường yêu cầu từ 6 đến 10 thông điệp, tùy thuộc vào các feature cần được sử dụng. Trong thực tế, có 3 flow thông dụng:

  • Full handshake với server authentication.

  • Abbreviated handshake để tiếp tục session trước đó.

  • Handshake với client authentication và server authentication.

Cấu trúc chung của Handshake:

struct {                                           
                                                    
  HandshakeType msg_type; # 1 byte                  
                                                    
  uint24 length; # 3 byte                           
                                                    
  HandshakeMessage message # tùy thuộc vào msg_type 
                                                    
} Handshake;                                       

Full handshake

Nếu client chưa từng tạo kết nối với server trước đó, 2 bên sẽ tiến hành thực hiện full handshake để đàm phán TLS session. Bốn hoạt động chính mà 2 bên sẽ thực hiện trong quá trình handshake:

  • Trao đổi các khả năng hỗ trợ(capabilities) và thống nhất các tham số kết nối.

  • Chứng thực cert.

  • Thông nhất khóa chia sẻ chung để bảo vệ session: master key.

  • Xác thực các thông điệp handshake không bị bên thứ 3 thay đổi.

Dưới đây là quá trình handshake TLS phổ biến nhất: giữa client không cần xác thực và server cần xác thực.

img-name
Full handshake với xác thực server

  1. Client bắt đầu handshake và gửi capabilities cho server.
  1. Server chọn các tham số kết nối.
  1. Server gửi chuỗi cert (certificate chain) của nó(chỉ có server cần xác thực).
  1. Tùy thuộc vào tùy chọn Key exchange, server gửi các thông tin cần thiết để tạo master secret (sẽ được nói kỹ hơn trong phần về Forward Secrecy).
  1. Server thông báo hoàn thành việc đàm phán.
  1. Client gửi các thông tin cần thiết để tạo master secret.
  1. Client báo cho server là sẽ chuyển sang quá trình mã hóa (client đã nhận đầy đủ các thông tin cần thiết).
  1. Client gửi MAC của thông điệp handshake nó đã gửi và nhận.
  1. Server báo cho client biết là sẽ chuyển sang quá trình mã hóa.
  1. Server gửi MAC của các thông điệp handshake nó đã nhận và gửi.

ClientHello

ClientHello luôn là thông điệp đầu tiên được gửi trong quá trình handshake, khi 2 bên muốn đàm phán lại(renegotiate).

img-name
Thông điệp ClientHello

Có thể thấy thông điệp có cấu trúc dễ hiểu, bao gồm các khả năng mà Client có thể cung cấp.

Random: 32 byte dữ liệu, với 28 byte được tạo ngẫu nhiên, 4 byte còn lại được tạo từ client clock. Cả client và server đều tạo trường random này để làm cho mỗi handshake là duy nhất và đóng vai trò chủ đạo trong xác thực, chống lại replay attack và xác thực tính toàn vẹn của dữ liệu trao đổi.

Session ID: Với lần đầu kết nối, session ID được bỏ trống. Trong những lần kết nối sau đó, trường ID có thể chứa 32 byte dữ liệu được sinh ngẫu nhiên để làm giá trị xác định session, giúp server locate được đúng session state trong cache.

ServerHello

Có cấu trúc giống với ClientHello, tuy nhiên chỉ có một option cho mỗi trường

img-name
Thông điệp ServerHello

Server không nhất thiết phải hỗ trợ version tốt nhất mà client đã offer, server có thể offer các version khác và hi vọng clinet sẽ chấp nhận.

Certificate

Server phải gửi Cert trừ khi giải thuật Key Exchange trong cipher suite là DH_anon(anonymous).

Client biết được public key của server qua cert. Thông điệp Certificate thường dùng để mang chuỗi cert X509 của server. Cert được cung cấp từng cái một theo ASN.1 DER encoding. Cert chính buộc phải gửi đầu tiên, các intermediate cert được gửi sau theo tính trình tự.

Server phải đảm bảo rằng cert phù hợp với cipher suite đã chọn. Ví dụ: thuật toán public key phải đúng với thuật toán trong cipher suite. Thêm nữa, một số kỹ thuật Key exchange dựa vào dữ liệu được trong cert and cert phải được ký bởi thuật toán mà client hỗ trợ. Do đó, server có thể được cấu hình với nhiều cert (mỗi cert có thể có chain khác nhau).

ServerKeyExchange

Được gửi ngay sau thông điệp Certificate(nếu có gửi), server chỉ gửi thông điệp này nếu thông tin trong Cert chưa đủ để Client trao đổi premaster secrecy, thường các giải thuật hỗ trợ Forward Secrecy: DHE_RSA, DHE_DSS, DH_anon, ECDHE_ECDSA.

ClientKeyExchange

Client tạo ra giá trị ngẫu nhiên gọi là premaster secret, mã hóa nó bằng public key của server.

ChangeCipherSpec

Thông điệp ChangeCipherSpec là signal thông báo bên gửi đã nhận đủ thông tin về các thông số kết nối, đã tạo các encryption key tương ứng và đang chuyển sang quá trình mã hóa.

Finished

Thông điệp Finished là signal thông báo quá trình handshake đã kết thúc. Nội dung thông điệp được mã hóa, điều đó cho phép 2 bên trao đổi dữ liệu cần thiết để kiểm chứng tính toàn vẹn của toàn bộ quá trình handshake.

Thông điệp này có trường verify_data, chứa toàn bộ giá trị băm của các thông điệp, gái trị băm được tính bằng pseudorandom function(PRF):

verify_data = PRF(master_secret, finished_label, Hash(handshake_messages))

Mỗi bên sử dụng label khác nhau: client finished với client, server finished với server.

Do thông điệp Finished được mã hóa và xác thực nên active attacker không thể thay đổi thông điệp và giả mạo giá trị verify_data. Với TLS 1.2 mặc định Finished có độ dài 12 bytes, tuy nhiên cipher suite cho phép sử dụng giá trị lớn hơn.

Handshake với Client authentication

img-name
Full handshake với xác thực server và client

Server gửi yêu cầu Client xác thực bằng việc gửi thông điệp CertificateRequest, thông điệp liệt kê danh sách những cert được chấp nhận. Client gửi cert của mình và chứng minh sự sở hữu với private key tương ứng qua thông điệp CertificateVerify.

CertificateRequest

struct{                                                              
                                                                      
  ClientCertificateType certificate_types; # những public key của cert được chấp nhận                                                  
                                                                        
  SignatureAndHashAlgorithm supported_signature_algorithm; #thuật toán ký hỗ trợ                                                 
                                                                        
  DistinguishedName certificate_authorities; # danh sách CA cấp cert được chấp nhận                                                  
                                                                      
} CertificateRequest;                                                

CertificateVerify

Để chứng minh sự sở hữu private key tương ứng với public key trong cert, Client gửi lại Signature của tất cả những thông điệp handshake đã trao đổi đến thời điểm này

struct{                                    
                                            
  Signature handshake_message_signature; 
                                            
} CertificateVerify;                       

Abbreviated Handshake

Original session resumption dựa trên việc client và server cùng giữ tham số session security trong một khoảng thời gian sau khi negotiated full handshake được chấm dứt. Server sẽ assign session với một identifier riêng biệt là session ID, giá trị session ID được gửi lại cho Client ở thông điệp ServerHello. Client muốn resume session trước đó sẽ submit session ID tương ứng vào thông điệp ClientHello. Nếu Server đồng thời muốn resume session đó, nó sẽ trả về chính giá trị session ID đó trong thông điệp ServerHello. Hai bên sẽ tạo set key mới dựa trên master secret đã thỏa thuận trước đó.

img-name
abbreviated handshake

Wireshark Example

  1. Handshake process

img-name
Handshake process

  1. ClientHello

img-name
Version, Gmt_time, Random_bytes

img-name
Supported cipher suites

img-name
Compression methods, Extensions

  1. ServerHello

img-name
ServerHello message, Session ID

  1. ServerHelloDone

img-name
Server Certificate, ServerHelloDone

  1. ClientKeyExchange

img-name
ClientKeyExchange

  1. ChangeCipherSpec

img-name
Client ChangeCipherSpec

  1. Finished

img-name
Finished message, Encrypted Handshake Message

img-name
Server Finished, Encrypted Handshake Message