Come descrive @klaustopher, il tunnel SSH utilizza uno scambio di chiavi Diffie-Hellman, per stabilire un segreto condiviso tra client e server; questo segreto condiviso viene utilizzato con la crittografia simmetrica per crittografare e verificare l'integrità di tutti i dati scambiati successivamente.
Come se stesso, DH + crypto simmetrico va bene, ma fa solo metà del lavoro. Quando il protocollo DH è stato eseguito, sia il client che il server sanno che ora hanno un tunnel sicuro con ... qualcuno. Ma loro non sanno chi . Sanno solo che questa sarà la stessa entità per tutta la durata della connessione. Quindi questo è vulnerabile agli aggressori attivi che impersonano il client, il server o entrambi. Il famoso attacco Man-in-the-Middle è un caso di doppia imitazione (l'attaccante agisce come server falso quando parla con il cliente e come cliente falso quando parla al server).
Per rendere sicuro un tunnel completamente sicuro per la trasmissione di dati riservati e comandi sensibili, il client e il server devono autenticarsi a vicenda. Nei primi passi del protocollo, il server firma ciò che invia (la sua metà del protocollo Diffie-Hellman); il client verifica quella firma relativamente alla chiave pubblica del server conosciuto (quella memorizzata dal client in .ssh/known_hosts
). Una volta che la firma è stata verificata, il client sa che sta facendo lo scambio di chiavi DH con il vero server, non con un aggressore che si presenta come il server previsto. Ciò significa che il cliente può inviare in modo sicuro dati riservati attraverso il tunnel. In particolare, una volta che il DH è stato fatto, i primi scambi vanno così:
- (server) Ok, nuovo client. Abbiamo fatto il DH, ho firmato, hai verificato, sai che sono il server giusto. Chi sei?
- (cliente) Sono Bob.
- (server) Dimostralo!
- (client) Ecco la mia password: bobisthemasteroftheuniverse
- (server) Ok, io do conosco un utente "Bob", e questa è la password giusta. Benvenuto, Bob.
Grazie all'autenticazione del server da parte del client (tramite l'algoritmo di verifica della firma), il client sa che può tranquillamente inviare la sua password nel tunnel.
Il protocollo SSH anche supporta l'autenticazione del client basata su firma. Il DH e la firma del server sono ancora fatti come in precedenza. Ma il protocollo quindi va così:
- (server) Ok, nuovo client. Abbiamo fatto il DH, ho firmato, hai verificato, sai che sono il server giusto. Chi sei?
- (cliente) Sono Bob. Ho una coppia di chiavi! L'ID della chiave pubblica è: (...)
- (server) Sì, vediamo a quello. Ecco un mucchio di dati casuali, ti sfido a firmarlo: (...)
- (client) Ecco una firma appena generata sulla tua sfida: (...)
- (server) Buono. Conosco un "Bob", il suo
.ssh/authorized_keys
contiene una chiave pubblica che corrisponde all'id che hai inviato e la tua firma sulla mia sfida si verifica correttamente riguardo a quella chiave pubblica. Benvenuto, Bob.
Più o meno la stessa cosa accade con HTTPS. Esistono molte differenze locali, ad es. il client HTTPS riconosce la chiave pubblica del server convalidando un certificato invece di ricordarlo da una visita precedente; e la cosa della password può assumere la forma di pagine Web reali; ma il succo dello scambio è lo stesso: il client si assicura che parli al server giusto verificando la sua chiave pubblica, e quindi il server si assicura che parli con il client giusto (se il server è veramente interessato a sapere < em> chi è il client) eseguendo una sorta di protocollo di autenticazione all'interno del tunnel.