Il protocollo HTTPS come è implementato da molti siti o browser ha un problema con il futuro.
Ipotizzando che qualcuno stia registrando tutto il traffico HTTPS di un sito adesso potrebbe solamente avere in mano dei dati illeggibili. Ma cosa succederebbe se venisse trafugata la chiave segreta, oppure se un domani i computer riuscissero in poche settimane a scardinare la chiave utilizzata?
C’è un passaggio fondamentale nei primi millisecondi del protocollo HTTPS:
Il browser, verificato il certificato, invia un messaggio al server che contiene un altro numero casuale cifrato con la chiave pubblica del server
Quindi, chi riuscisse a calcolare o trafugare la chiave privata del server potrebbe decifrare tutto il traffico HTTPS protetto con quella coppia di chiavi, ipoteticamente salvato negli anni, che fino a quel momento non era decifrabile (retrospective decryption).
Lo scambio di una chiave segreta condivisa su un canale non sicuro è un problema non nuovo. Whitfield Diffie, Martin Hellman e Ralph Merkle avevano trovato una soluzione già negli anni ’70 del secolo scorso elaborando quello che poi sarebbe diventato il protocollo Diffie-Hellman per lo scambio di chiavi (brevetto US4200770 ora scaduto).
Anche in questo caso bisogna fare un passo indietro per vedere come funzionano le cose dietro le quinte.
Teniamo sempre ben presente gli scopi di una sessione HTTPS o, più in generale, TLS: dobbiamo essere sicuri sia che i dati scambiati non siano leggibili da terzi sia che stiamo scambiando i dati con l’entità giusta. Il secondo problema viene risolto dall’infrastruttura a chiave pubblica, il primo dalla crittografia ed è quello che ci interessa analizzare.
Quando viene stabilita una sessione TLS (di cui HTTPS è una delle tante implementazioni) il client dichiara i protocolli di cifratura che supporta e il server ne sceglie uno di suo gradimento, il che non significa che scelga il migliore dal punto di vista della sicurezza. Questo perché alcuni server possono decidere di utilizzare un protocollo più debole per evitare di sovraccaricare le CPU, a scapito della sicurezza.
I protocolli possibili sono molti, sono definiti nello standard TLS (RFC5246); all’interno di questi alcuni definiscono anche il protocollo utilizzato per scambiare la chiave utilizzata per cifrare la sessione. Non dobbiamo dimenticare che una sessione TLS è cifrata con una chiave simmetrica generata al momento del dialogo iniziale tra client e server. Tra i protocolli suscettibili di una decodifica ex post ci sono RSA, DH_RSA, DH_DSS. Mentre tra i protocolli di scambio della chiave di sessione che implementano la PFS (perfect forward secrecy, segretezza perfetta a posteriori) ci sono DHE_RSA, DHE_DSS, ECDHE_ECDSA, ECDHE_RSA (vedi l’appendice C di RFC5246 e la sezione 2 di RFC4492). Questi ultimi scambiano una chiave che in gergo crittografico viene definita ephemeral, ovvero una chiave temporanea utilizzata solamente per quella sessione che non è calcolabile in alcun modo anche conoscendo tutto il traffico del server.
Bisogna riconoscere che, alla luce degli eventi degli ultimi mesi, il perfect nella definizione della segretezza perfetta a posteriori è un esercizio di sano ottimismo. Di sicuro la PFS rende la vita molto difficile a chi un domani voglia attaccare con la forza bruta una grossa mole di comunicazioni cifrate perché l’attaccante deve calcolare la chiave di cifratura per ogni sessione.
Alla luce di tutto questo, sarebbe legittimo presumere che la PFS sia usata da tutti. Illusi.
Si può facilmente verificare guardando il log di Apache (versione 2.2.15 su CentOS 6) che riporta l’algoritmo di cifratura utilizzato per accedere in HTTPS ad un sito che dispone di una chiave regolarmente emessa da una CA:
[24/Nov/2013:08:40:13] 2001:db8::1701 TLSv1 DHE-RSA-CAMELLIA256-SHA [24/Nov/2013:08:40:12] 2001:db8::cafe TLSv1 DHE-RSA-AES256-SHA [24/Nov/2013:08:42:33] 2001:db8::dead:beef TLSv1 AES128-SHA
La prima riga è di Firefox 25.0, la seconda di Chrome 29.0, la terza di Internet Explorer 10.0, tutti e tre aggiornati all’ultima versione disponibile al momento del test. Come si può vedere, Chrome e Firefox negoziano una chiave di sessione attraverso il protocollo Diffie-Hellman ephemeral, che garantisce la PFS, mentre Internet Explorer utilizza il vecchio metodo RSA (quello descritto in apertura) che si serve della chiave pubblica del server per scambiare la chiave di sessione.
Internet Explorer supporta formalmente la PFS, ma con molte restrizioni, tali per cui di fatto la PFS non viene utilizzata quasi mai. Anche la documentazione Microsoft del protocollo TLS aggiornata al 13 novembre 2013 dice chiaramente che la chiave di sessione viene cifrata utilizzando la chiave pubblica del server:
Un motivo in più per riflettere sul livello di sicurezza offerto da Microsoft e evitare il più possibile di utilizzare Internet Explorer.
Come possiamo verificare con il nostro browser qual è l’algoritmo utilizzato per scambiare la chiave di sessione?
Tenendo valido l’elenco di protocolli PFS indicato sopra, per verificare l’algoritmo di scambio chiavi utilizzato in Chrome si clicca sul lucchetto verde e si selezione Connessione:
Con Firefox si clicca sul lucchetto, quindi sul pulsante per avere ulteriori informazioni:
Non sono riuscito a trovare una documentazione affidabile in merito per Internet Explorer, un altro motivo per evitare quel browser il più possibile.
L’utilizzo della segretezza perfetta a posteriori non è una garanzia assoluta e tombale di segretezza, ma è una ragionevole sicurezza che in un futuro prossimo chi sta registrando e mettendo da parte le nostre comunicazioni crittografate tramite TLS non abbia facile gioco a decifrarle.
Come sottolinea anche l’EFF, la PFS è uno dei pilastri per proteggere il diritto non negoziabile della privacy.
Lascia un commento