GPG e crittografia asimmetrica

Nell'esercizio precedente si è visto come il comando ssh utilizzi la crittografia asimmetrica per verificare l'identità. In origine, questa era stata creata con lo scopo di trasmettere messaggi cifrati.

Scopo di questa esercitazione è generare una chiave con lo scopo di ricevere messaggi criptati. Gli algoritmi usuali sono gli stessi utilizzati per SSH, ma il software che si usa per l'invio di messaggi è diverso. Su Linux, di solito è gpg.

Generare una chiave

Come per ssh, è necessario generare una coppia di chiave pubbliche e segrete; l'algoritmo utilizzato determinerà il significato, ovvero se siano collegati al problema di fattorizzare numeri primi, o al logaritmo discreto, o a curve ellittiche.

Si utilizzi il comando gpg --list-secret-keys per ottenere la lista delle chiavi segrete presenti sul sistema.

Non avendo creato alcuna chiave, ci si aspetta una lista vuota. Tuttavia, al primo tentativo il comando può restituire dell'output dicendo che, non essendo mai stato lanciato, ha inizializzato il database delle chiavi.

È molto comune per i comandi Unix che, nel caso non debbano restituire nulla, semplicemente non stampino nulla sullo schermo; dunque, nel caso non ci siano chiavi, il comando sopra non genera nessun output — in ogni caso, non c'è da preoccuparsi.

A questo punto è necessario creare il nostro primo paio di chiavi; per come funziona gpg, è necessario associarle ad un indirizzo email. Come esempio, utilizzeremo pippo@pluto.com. Ovviamente, si utilizzi un indirizzo di cui si è veramente in possesso.

Creare una nuova coppia di chiavi utilizzando il comando gpg --gen-key. Sarà necessario fornire il proprio nome e cognome e l'indirizzo e-mail valido. Verrà anche richiesto di scegliere una passphrase, ovvero una password che verrà richiesta ad ogni utilizzo della chiave.

Una volta generata la chiave, è possibile controllare che sia presente nel sistema utilizzando il comando gpg --list-secret-keys, come fatto in precedenza. Questa volta, ci si aspetta di ottenere una lista con un unico elemento, la nuova chiave.

Cifrare un messaggio per se stessi

Ora che si ha chiave a disposizione, si provi a cifrare un messaggio per noi stessi, per poi vedere se si riesce a decriptarlo.

Si esegua il comando
$ gpg --armor -e -r pippo@pluto.com
e si digiti del testo contenente il messaggio da cifrare; si termini il messaggio usando la combinazione CTRL + D, che serve a mandare il segnare di fine del file.

Le opzioni del comando gpg hanno il seguente significato:

Se tutto va per il verso giusto, si dovrebbe avere il messaggio criptato sullo schermo, delimitato dai blocchi -----BEGIN PGP MESSAGE----- e -----END PGP MESSAGE-----.

Si utilizzi ora il comando gpg -d per avviare gpg in modalità decrittazione; a questo punto, si può incollare il testo crittato (compresi i blocchi BEGIN ed END). Il programma chiede la passphrase, e ci si troverà il testo decriptato.

Cifrare e spedire un messaggio

Si può ora provare a spedire un messaggio a qualcun altro, cifrandolo per il destinatario, ma firmandolo per garantirne l'autenticità. Per effettuare quest'operazione è necessario ottenere la chiave del destinatario. A questo scopo esistono i server di chiavi, dove è possibile caricare la propria chiave crittografica per fare in modo che gli altri la possano trovare.

Per il momento, ci si accontenterà di accordarsi con un altro collega all'interno dello stesso gruppo di lavoro, e collegato alla stessa macchina (labN). È possibile utilizzare il comando write per scrivere un messaggio sul terminale di un altro utente.

Si utilizzi il comando who per controllare quali altri utenti sono collegati alla stessa macchina. Si scelga lo username di un proprio collega, e si usi il comando write utente per iniziare a scrivere. Terminare il messaggio con la combinazione di tasti CTRL+D.

Combinare il comando echo con il comando write permette di comunicare con altri utenti collegati alla stessa macchina in modo leggermente meno faticoso, sebbene un po' rudimentale. Effettuare qualche prova comunicando con un proprio collega nello stesso gruppo, o anche in un'altra macchina.

Si provi a stampare la propria chiave pubblica con il comando
$ gpg --armor --export -r me@gmail.com
dove me@gmail.com è l'indirizzo e-mail associato alla chiave in precedenza. Questo dovrebbe stampare parecchie linee di testo, delimitate da una stringa -----BEGIN PGP PUBLIC KEY----- e -----END PGP PUBLIC KEY-----. Si utilizzi il simbolo | per spedire la propria chiave pubblica ad un altro utente, identificato tramite il comando who:
$ gpg --export -r me@gmail.com | write utente
dove utente è il nome dell'altro utente scelto.

A questo punto la chiave è stata spedita, ed è necessario capire come importarla.

L'utente che riceve la chiave, può copiare il testo fra i delimitatori (delimitatori compresi), ed importarlo in gpg con il comando:
$ echo "..." | gpg --import
Al posto dei puntini va incollata la chiave pubblica ricevuta (e copiata). Il comando echo permette di stampare una stringa (la nostra chiave pubblica), e il simbolo | la usa come input per il comando successivo.

Una volta effettuata questa procedura, è possibile cifrare un messaggio come fatto prima, e spedirlo tramite write

$ echo "..." | write utente
Anche questa volta al posto dei puntini andrà sostituito il messaggio criptato ottenuto dal comando gpg --armor -s -e -r destinatatio@dominio.com. L'utente che riceve il messaggio, potrà decriptarlo con il comando
echo "..." | gpg -d
Ancora una volta incollando la stringa corretta al posto dei puntini.

A questo punto, ci si dovrebbe essere impratichiti a sufficienza con la cifratura, per provare a mandare un messaggio ad un indirizzo e-mail reale.

Si scarichi la chiave associata all'indirizzo e-mail leonardo.robol@unipi.it, tramite il comando
$ gpg --keyserver keys.gnupg.net --recv-key 00674B88694715A1658904C330E75B283A6456FD
Si invii poi un messaggio criptato e firmato, con il comando
gpg --armor -e -s -r leonardo.robol@unipi.it | mail -s '[LCMC] NNNNNN' leonardo.robol@unipi.it
Suggerimento: Prima di provare il comando sopra, lo si testi utilizzando solo la prima parte, a sinistra del simbolo |; questo stamperà il messaggio senza mandare l'email, ed in questo modo è possibile verificare che il comando non dia errori.