- Prima del TLS c'è TCP: tre pacchetti solo per aprire il canale
ClientHelloè il nome reale del messaggio - lo vedi in Wireshark, è nell'RFC- Browser e server derivano la stessa chiave senza mai trasmettersela (Diffie-Hellman)
- Ogni sessione usa chiavi nuove e le butta via - anche se qualcuno ruba la chiave del server tra un anno, il traffico di oggi resta illeggibile
▶ $ history
- openssl s_client -connect google.com:443 -showcerts
- openssl s_client -connect dominio.com:443 2>/dev/null | openssl x509 -noout -dates
- openssl s_client -connect google.com:443 </dev/null 2>/dev/null | openssl x509 -noout -text | grep -E "Subject|Issuer|Not After"
Ogni volta che scrivi https:// nel browser e premi invio, sullo sfondo succede qualcosa che la maggior parte degli sviluppatori web dà per scontato. Il lucchetto verde appare, la connessione è "sicura", si va avanti.
Ma sicura come? Sicura contro chi? E perché qualcuno che intercetta il tuo traffico non può leggerlo, anche se vede ogni singolo pacchetto che passa?
Questa è la storia di quei 250 millisecondi.
Il contesto - tre tipi di crittografia in gioco#
Prima di aprire il browser, conviene capire i mattoni di base. HTTPS usa tre approcci crittografici diversi, ciascuno per risolvere un problema specifico:
Simmetrica (AES) → stessa chiave cifra e decifra → veloce
problema: come la condividi in modo sicuro?
Asimmetrica (RSA) → chiave pubblica cifra, privata decifra → lenta
risolve la distribuzione delle chiavi
DH / ECDHE → due parti derivano la stessa chiave senza
mai trasmetterla sulla rete → risolve PFSHTTPS le usa tutte e tre: l'asimmetrica per verificare l'identità, il DH per negoziare una chiave senza inviarla, la simmetrica per cifrare i dati. Ognuna dove ha senso.
TCP: prima ancora di parlare di HTTPS#
La connessione HTTPS comincia con un TCP handshake. Non TLS, non crittografia - solo tre pacchetti per stabilire un canale affidabile:
Client → Server SYN "possiamo parlare?"
Server → Client SYN-ACK "sì, sono pronto. tu?"
Client → Server ACK "ok, inizio"Solo dopo che questo è completato, il browser inizia il TLS handshake. TCP è il pavimento su cui costruisce tutto il resto.
Client Hello: il browser presenta le sue carte#
Sì, si chiama davvero così. ClientHello è il nome esatto del messaggio definito nell'RFC 8446 (la specifica di TLS 1.3, sezione 4.1.2). Non è una metafora - se apri Wireshark durante una connessione HTTPS, lo vedi scritto proprio così nel payload.
Il browser manda un ClientHello che contiene:
- Le versioni TLS che supporta (oggi tipicamente TLS 1.2 e 1.3)
- Gli algoritmi crittografici che conosce (cipher suites)
- Un numero casuale che servirà dopo
Il server risponde con un ServerHello: sceglie la versione TLS e la cipher suite, poi manda il suo certificato.
Il certificato e la catena di fiducia#
Il certificato è un documento digitale firmato da una Certificate Authority (CA). Contiene:
- La chiave pubblica del server
- Il dominio a cui appartiene (
example.com) - La firma crittografica della CA che lo ha emesso
Il browser non conosce il certificato del sito - ma conosce già le CA. Nel tuo sistema operativo e nel browser ci sono circa 170 Root CA preinstallate. La verifica segue una catena:
graph TD
Root["Root CA - preinstallata nel tuo OS"]
Inter["Intermediate CA - firmata dalla Root"]
Cert["Certificato del sito - firmato dalla Intermediate"]
Root --> Inter --> Cert
Il browser risale la catena. Se trova una Root CA che riconosce, il certificato è valido. Se la catena si spezza - warning e blocco.
Tre cose vengono verificate:
- La firma è valida e risale a una Root CA fidata?
- Il certificato non è scaduto?
- Il dominio corrisponde a quello a cui ti stai connettendo?
Tutto ok → lucchetto verde.
Un certificato valido non significa che il sito è sicuro. Significa che la connessione è cifrata. Un attaccante può avere un certificato valido per un dominio di phishing - il lucchetto verde non garantisce l'identità del business, solo che stai parlando con il server giusto.
Diffie-Hellman: la chiave che nessuno ha mai trasmesso#
Questo è il passaggio più controintuitivo. Browser e server devono concordare una chiave simmetrica per cifrare i dati - ma non possono semplicemente inviarsela. Se qualcuno sta ascoltando, la intercetterebbe.
Prima della matematica, c'è un'analogia che aiuta: i secchi di tinta.
Alice e Bob vogliono un colore segreto condiviso senza doversi dire i colori privati:
- Concordano pubblicamente un colore base - giallo. Tutti lo sanno, non è un segreto.
- Alice sceglie in segreto il rosso. Lo mescola col giallo → manda arancione a Bob.
- Bob sceglie in segreto il blu. Lo mescola col giallo → manda verde ad Alice.
- Alice prende il verde di Bob, ci aggiunge il suo rosso segreto → marrone.
- Bob prende l'arancione di Alice, ci aggiunge il suo blu segreto → marrone.
Stesso colore finale. Ma perché un attaccante che intercetta tutto - giallo, arancione, verde - non riesce a ricavare il marrone?
Perché non può semplicemente mescolare arancione e verde. Arancione è giallo+rosso, verde è giallo+blu: mescolandoli ottiene giallo+giallo+rosso+blu - un colore diverso, con il giallo in eccesso. Per arrivare al marrone gli serve uno dei due segreti privati, rosso o blu. E quelli non sono mai usciti dalle rispettive macchine.
L'unica strada è separare il rosso dall'arancione - cioè togliere il giallo dalla miscela. Con la tinta è fisicamente impossibile. Con i numeri, il problema equivalente si chiama logaritmo discreto ed è computazionalmente infattibile con chiavi abbastanza grandi.
La soluzione è ECDHE (Elliptic Curve Diffie-Hellman Ephemeral). Il principio è lo stesso, con i numeri al posto dei colori:
sequenceDiagram
participant B as Browser
participant S as Server
B->>S: Parametro pubblico A
S->>B: Parametro pubblico B
note over B: Calcola chiave con A e il suo segreto privato
note over S: Calcola chiave con B e il suo segreto privato
note over B,S: Entrambi hanno la stessa chiave simmetrica
note over B,S: Nessuno ha mai mandato la chiave sulla rete
A e B sono parametri pubblici - chiunque li vede. Ma la chiave derivata richiede il segreto privato di ciascun lato, che non esce mai dalla macchina. Matematicamente, entrambi arrivano allo stesso risultato senza averlo comunicato.
Perfect Forward Secrecy: perché la E di ECDHE è importante#
La E sta per Ephemeral - effimero. Per ogni sessione TLS vengono generate coppie di chiavi DH completamente nuove, usate una volta sola e poi scartate:
Sessione 1: a1, b1 → chiave simmetrica K1 → scartata
Sessione 2: a2, b2 → chiave simmetrica K2 → scartata
Sessione 3: a3, b3 → chiave simmetrica K3 → scartataQuesto garantisce la Perfect Forward Secrecy. Senza PFS, uno scenario classico è: un attaccante registra traffico cifrato oggi, ruba la chiave privata del server tra sei mesi, e decifra tutto il traffico passato. Con ECDHE questo è impossibile - le chiavi effimere non esistono più.
TLS 1.3 (2018) rende ECDHE obbligatorio. Non è più una scelta - è un requisito.
AES: finalmente i dati#
Stabilita la chiave simmetrica, tutto il resto della conversazione è cifrato con AES. Veloce, efficiente, standard. L'asimmetrica e il DH hanno fatto il loro lavoro - ora passa in secondo piano.
Il quadro completo in sequenza:
sequenceDiagram
participant B as Browser
participant S as Server
B->>S: TCP SYN
S->>B: TCP SYN-ACK
B->>S: TCP ACK
B->>S: Client Hello - versioni TLS e algoritmi supportati
S->>B: Server Hello - algoritmo scelto e certificato
B->>B: Verifica catena certificato fino a Root CA
B->>S: Parametro pubblico DH
S->>B: Parametro pubblico DH
note over B,S: Entrambi derivano la stessa chiave simmetrica
B->>S: Dati cifrati con AES
S->>B: Risposta cifrata con AES
Nella pratica - ispezionare un certificato#
openssl s_client è il modo più diretto per vedere cosa sta succedendo sotto il lucchetto verde.
# Vedere il certificato di un sito e la catena
openssl s_client -connect google.com:443 -showcerts
# Verificare la scadenza
echo | openssl s_client -connect dominio.com:443 2>/dev/null | openssl x509 -noout -dates
# Subject, Issuer, scadenza in un colpo
openssl s_client -connect google.com:443 </dev/null 2>/dev/null \
| openssl x509 -noout -text \
| grep -E "Subject|Issuer|Not After"Un certificato scaduto è un alert immediato: o il sito è abbandonato, o qualcosa è andato storto nella gestione del rinnovo. In entrambi i casi vale la pena investigare.
exit 0#
Il lucchetto verde è il risultato di un sistema a tre strati che si sono evoluti per risolvere problemi distinti: distribuire chiavi senza trasmetterle, verificare identità senza un canale sicuro preesistente, cifrare dati velocemente una volta che i due problemi precedenti sono risolti.
Ogni volta che appare quel lucchetto, qualcuno ha già fatto tre handshake in meno di un secondo. E se un attaccante registra il traffico oggi, tra un anno non gli servirà a niente - le chiavi sono già sparite.
Concetti correlati: crittografia · tcp-udp
Approfondimenti: La firma digitale · Crittografia pt. VIII - corsobitcoin.com




