TLS Handshake

Indice dei contenuti

    Il TLS handshake è la procedura di negoziazione con cui un client e un server stabiliscono una sessione TLS sicura prima di scambiare dati applicativi. Durante l’handshake le due parti concordano la versione del protocollo e la suite crittografica, il server dimostra la propria identità tramite certificato X.509, e vengono derivate le chiavi simmetriche che proteggeranno la comunicazione successiva. L’handshake è il momento in cui la sicurezza dell’intera sessione viene stabilita o compromessa.

    TLS 1.3: handshake a 1-RTT

    TLS 1.3 (RFC 8446, 2018) ha semplificato radicalmente il handshake rispetto a TLS 1.2, riducendo la latenza a 1 RTT (round-trip time) e migliorando la sicurezza eliminando le suite crittografiche deboli.

    Client                                    Server
      |                                          |
      |── ClientHello ────────────────────────▶ |
      |   (versione, key_share, cipher_suites)   |
      |                                          |
      |◀─ ServerHello ──────────────────────── |
      |   (key_share, cipher_suite scelta)       |
      |◀─ {Certificate} ───────────────────── |
      |◀─ {CertificateVerify} ──────────────── |
      |◀─ {Finished} ───────────────────────── |
      |                                          |
      |── {Finished} ───────────────────────▶ |
      |                                          |
      |═══ Dati applicativi cifrati (AEAD) ════ |

    I messaggi tra {} sono già cifrati con chiavi derivate dopo il primo scambio ECDHE.

    ClientHello: il client invia le versioni TLS supportate, le suite crittografiche accettate e — novità TLS 1.3 — già le key shares ECDHE per le curve che si aspetta il server accetti (tipicamente X25519 e P-256). Questo permette al server di completare lo scambio di chiavi nella stessa risposta, risparmiando un RTT.

    ServerHello + chiavi derivate: il server sceglie la suite crittografica, seleziona la key share del client, calcola il segreto condiviso ECDHE e da esso deriva le chiavi di cifratura della sessione (handshake keys). Tutto ciò che segue è già cifrato.

    Certificate + CertificateVerify: il server invia il certificato (ora cifrato — non visibile a chi intercetta il traffico) e una firma sul transcript dell’handshake con la propria chiave privata. Questo prova che il server possiede la chiave privata corrispondente al certificato.

    Finished: MAC sull’intero transcript dell’handshake. Garantisce che nessun messaggio sia stato alterato in transito.

    TLS 1.3: 0-RTT (early data)

    TLS 1.3 introduce la modalità 0-RTT: se client e server si sono già connessi in precedenza, il client può inviare dati applicativi già nel primo messaggio, prima del completamento dell’handshake, usando una pre-shared key (PSK) derivata dalla sessione precedente. Riduce la latenza a zero RTT ma con un costo: i dati 0-RTT non sono protetti dalla forward secrecy e sono vulnerabili a replay attack — un attaccante che cattura il messaggio 0-RTT può ritrasmetterlo al server. Va usato solo per operazioni idempotenti (es. GET, non POST che modificano stato).

    TLS 1.2 vs. TLS 1.3

    AspettoTLS 1.2TLS 1.3
    RTT per handshake2 RTT1 RTT
    Forward secrecyOpzionale (dipende dalla suite)Obbligatoria (solo ECDHE/DHE)
    Suite crittograficheMolte, incluse deboli (RC4, 3DES, export)Solo AEAD moderne (AES-GCM, ChaCha20-Poly1305)
    RSA key exchangeSì (no forward secrecy)Eliminato
    RenegotiationSì (fonte di vulnerabilità)Eliminata
    Certificato visibileSì, in chiaro durante handshakeCifrato (Encrypted Client Hello in bozza)

    Verifica del certificato lato client

    Durante l’handshake, il client verifica il certificato del server:

    1. La catena di certificati risale a una CA root nel trust store del client
    2. Nessun certificato nella catena è scaduto
    3. Nessun certificato nella catena è stato revocato (OCSP stapling)
    4. Il Common Name o un Subject Alternative Name corrisponde al hostname richiesto
    5. Il certificato è stato firmato con l’algoritmo dichiarato

    Se una qualsiasi verifica fallisce, la connessione viene interrotta con un alert TLS. Ignorare errori di certificato (certificate errors) — pratica purtroppo comune in sviluppo — apre la porta ad attacchi MitM.

    Ultimo aggiornamento: