RFC5077 TLS Session Resumption without Server-Side State
概述
这篇 RFC 废弃了 "RFC4507: Transport Layer Security (TLS) Session Resumption without Server-Side State"
主要描述了在不需要维护服务器状态的情况下如何重启一个 TLS Session
状态总归是要有的, 比如加密套件, 加密的主密钥, 它们都保存在一个由服务器知道的密钥加密过的一个 ticket 里
it stores its session state (such as ciphersuite and master secret) to a ticket that is encrypted and integrity-protected by a key known only to the server.
The ticket is distributed to the client using the NewSessionTicket
This message is sent during the TLS handshake before the ChangeCipherSpec message, after the server has successfully verified the client's Finished message
握手流程
- Figure 1: Message Flow for Full Handshake Issuing New Session Ticket
Client Server
ClientHello
(empty SessionTicket extension)-------->
ServerHello
(empty SessionTicket extension)
Certificate*
ServerKeyExchange*
CertificateRequest*
<-------- ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished -------->
NewSessionTicket
[ChangeCipherSpec]
<-------- Finished
Application Data <-------> Application Data
- Figure 2: Message Flow for Abbreviated Handshake Using New Session
Client Server
ClientHello
(SessionTicket extension) -------->
ServerHello
(empty SessionTicket extension)
NewSessionTicket
[ChangeCipherSpec]
<-------- Finished
[ChangeCipherSpec]
Finished -------->
Application Data <-------> Application Data
- Figure 3: Message Flow for Server Completing Full Handshake Without Issuing New Session Ticket
Client Server
ClientHello
(SessionTicket extension) -------->
ServerHello
Certificate*
ServerKeyExchange*
CertificateRequest*
<-------- ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished -------->
[ChangeCipherSpec]
<-------- Finished
Application Data <-------> Application Data
Session Ticket 扩展
The server uses a zero-length SessionTicket extension to indicate to
the client that it will send a new session ticket using the
NewSessionTicket handshake message described in Section 3.3. The
server MUST send this extension in the ServerHello if it wishes to
issue a new ticket to the client using the NewSessionTicket handshake
message. The server MUST NOT send this extension if it does not
receive one in the ClientHello.
This message is sent by the server during the TLS handshake before
the ChangeCipherSpec message.
This message MUST be sent if the server included a SessionTicket extension in the ServerHello.
This message MUST NOT be sent if the server did not include a
SessionTicket extension in the ServerHello.
This message is included in the hash used to create and verify the Finished message.
In the case of a full handshake, the server MUST verify the client's
Finished message before sending the ticket.
The client MUST NOT treat the ticket as valid until it has verified the server's Finished message.
If the server determines that it does not want to include a ticket after it has included the SessionTicket extension in the ServerHello, then it sends a zero-length ticket in the NewSessionTicket handshake message.
struct {
HandshakeType msg_type;
uint24 length;
select (HandshakeType) {
case hello_request: HelloRequest;
case client_hello: ClientHello;
case server_hello: ServerHello;
case certificate: Certificate;
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
case session_ticket: NewSessionTicket; /* NEW */
} body;
} Handshake;
struct {
uint32 ticket_lifetime_hint;
opaque ticket<0..2^16-1>;
} NewSessionTicket;