03GSDOV - Sicurezza dei sistemi informatici

Transcript

03GSDOV - Sicurezza dei sistemi informatici
Crittografia con OpenSSL – crittografia simmetrica
Laboratorio del corso “Sicurezza dei sistemi informatici” (03GSDOV)
Politecnico di Torino – AA 2016/17
Prof. Antonio Lioy
preparata da:
Cataldo Basile ([email protected])
Andrea Atzeni ([email protected])
v. 2.41 (16/10/2014)
Scopo dell’esercitazione
Scopo dell’esercitazione è sperimentare le procedure e le problematiche associate all’uso delle diverse primitive
crittografiche. L’esercitazione è basata sull’uso estensivo di OpenSSL (http://www.openssl.org/), una
libreria crittografica rilasciata come software open-source con licenza BSD e disponibile su un ampio insieme
di piattaforme, inclusi Linux e Windows.
L’esercitazione è essenzialmente basata sull’uso di programmi funzionanti da linea di comando. Usando
OpenSSL si possono invocare varie funzioni crittografiche attraverso la shell digitando:
openssl command [ command opts ] [ command args ]
Per il corretto svolgimento di questa esercitazione sarà necessario usare i comandi:
enc dgst rand speed
che saranno presentati di seguito. Per la lista completa delle opzioni ed una descrizione dettagliata dei comandi
consigliamo di visionare le relative pagine man.
I file ed i programmi necessari allo svolgimento dei singoli esercizi sono disponibili scaricando l’archivio
http://security.polito.it/˜lioy/03gsd/03gsd_1617_lab02_materiale.zip.
Per decomprimerli potete usare il seguente comando:
7z x 03gsd 1617 lab02 materiale.zip
openssl enc
Il comando enc permette di cifrare e decifrare blocchi di dati usando un gran numero di algoritmi crittografici.
Ad esempio, per visualizzare la lista dei parametri accettati dal comando enc, si può eseguire il comando:
openssl enc -h
Qui di seguito riportiamo la sintassi generale ed i parametri più importanti (si ricorda che i comandi in parentesi
quadre sono opzionali):
openssl enc [-algoritmo di encryption] [-e] [-d] [-K chiave] [-iv vettore]
[-in file input] [-out file output] [-nopad] [-p]
in cui:
1
• -algoritmo di encryption, serve ad indicare l’algoritmo da usare per svolgere le operazioni di crifratura
simmetrica (es. -aes128, -aes-cbc-256, -rc4, la lista completa si ha con openssl enc -h);
• -e richiede di svolgere la cifratura (encryption) e naturalmente esclude l’opzione -d;
• -d richiede di svolgere la decifratura e naturalmente esclude l’opzione -e;
• -K chiave, forza l’uso della chiave chiave per le operazioni di crittografia simmetrica (ATTENZIONE:
openssl è case sensitive, è importante per questa esercitazione usare la K “maiuscola”);
• -iv vettore, per usare il vettore di inizializzazione vettore;
• -in file input per cifrare il file file input;
• -out file output per salvare in file output l’output di enc;
• -nopad, non applica il padding (ATTENZIONE: in questo caso, per algoritmi a blocchi, la lunghezza
del dato da cifrare deve essere necessariamente un multiplo della lunghezza del blocco o l’operazione
fallirà);
• -p, per stampare su standard output la chiave ed il vettore di inizializzazione usati (in realtà anche il
cosiddetto salt generato in maniera pseudo-casuale da OpenSSL).
openssl dgst
Il comando dgst permette di calcolare il digest di un blocco di dati usando uno dei diversi algoritmi di digest
supportati dalla libreria OpenSSL. Per visualizzare la lista dei parametri accettati dal comando dgst potete
eseguire il comando:
openssl dgst -h
Per una descrizione approfondita del comando dgst potete richiamare la sua pagina man:
man dgst
Qui di seguito la sintassi generale ed i parametri più importanti:
openssl dgst [-algoritmo di digest] [-binary] [-hmac chiave] [-out output file] input file(s)
in cui:
• -algoritmo di digest, serve ad indicare l’algoritmo da usare per svolgere le operazioni di digest (es. -md5,
-sha1, la lista completa si ha con openssl dgst -h);
• -binary per indicare che l’output deve essere prodotto in formato binario (OpenSSL produce di default
l’output in formato testuale);
• -hmac chiave per indicare che deve essere prodotto in output l’HMAC calcolato con la chiave chiave;
• -out output file, per salvare in output file il digest;
• input file(s), per indicare i file di cui calcolare il digest (ATTENZIONE: dgst non usa l’opzione -in, ma
i file di cui calcolare il digest sono passati come ultimi argomenti sulla riga di comando).
openssl speed
Col comando speed si possono verificare le prestazioni di uno degli algoritmi disponibili in OpenSSL:
openssl speed [nome algoritmo1 nome algoritmo2 ...]
Se non specificate nessun nome di algoritmo, saranno verificate le prestazioni di tutti gli algoritmi in OpenSSL
(questo processo può essere lungo).
2
openssl rand
Col comando rand si possono generare numbyte casuali e salvarli nel file file name:
openssl rand -out file name numbyte
Altri comandi
Nel corso dell’esercitazione dovrete scambiarvi dati da un computer all’altro col comando scp. Abilitate quindi
il server ssh:
/etc/init.d/ssh start
oppure
service ssh start
1 Algoritmi di cifratura simmetrica
1.1
Cifratura simmetrica
Provate a cifrare un blocco di dati col comando OpenSSL enc. Scegliete una chiave di 32 cifre esadecimali e
scrivetela qui
→
Create un file di testo chiamato ptext contenente il messaggio da cifrare, ad esempio il seguente testo:
Questo e’ il mio grande segreto
Dopo averlo salvato, verificate che sia lungo esattamente 32 byte (ls -l), pur non essendo indispensabile per
il prossimo esercizio, lo sarà in uno degli esercizi successivi.
Usate gli algoritmi DES, 3DES, RC4 e AES (con chiave di 128 bit) per cifrare il file ptext con la chiave da
voi scelta. Il messaggio cifrato deve essere salvato in un file chiamato ctext.
Scoprite la stringhe di comando OpenSSL da usare per svolgere le operazioni sopra descritte e scrivetele. Fate
in modo che il comando visualizzi la chiave e l’IV (se l’algoritmo usa un IV) effettivamente usati:
→
Quali altre scelte dobbiamo compiere nel caso di DES, 3DES e AES? Scrivetele:
→
Confrontate la lunghezza dei file ctext generati nei vari casi e quella di ptext: motivate le differenze osservate.
→
Riassumendo: cosa succede usando il seguente comando?
openssl enc -e -in ptext -out ctext -K chiave -iv IV -aes-128-cbc -nopad -p
Nel caso abbiate usato un messaggio in chiaro differente, provate ad eseguire l’operazione col messaggio sopra
suggerito.
3
→
Cosa succede usando il seguente comando?
openssl enc -e -in ptext -out ctext -K chiave -rc4 -p
Spiegare la differenza tra i due comandi precedenti.
Ora provate a decifrare il file ctext per entrambi i comandi precedenti. Salvate il messaggio decifrato in un
file chiamato dtext. Scoprite la stringa di comando OpenSSL usata per la decifratura e scrivetela:
→
Verificate che la decifratura sia stata eseguita correttamente.
Cosa succede usando il seguente comando?
openssl enc -e -in ptext -out ctext -aes-128-cbc -p
Come è stata calcolata la chiave di cifratura? E l’IV?
→
1.2
Attacco a forza bruta
A questo punto non resta altro che provare a rompere un algoritmo crittografico con un attacco a forza bruta!
Formate delle coppie (diciamo Alessandro e Caterina) e procedete come segue:
1. Alessandro prepara un nuovo messaggio di testo nel file ptext, sceglie una chiave lunga 4 bit (ossia un
carattere esadecimale) e cifra il messaggio col seguente comando:
openssl enc -e -in ptext -out ctext ale -K chiave corta -rc4
2. Caterina crea l’utente caterina
useradd caterina
passwd caterina
mkdir /home/caterina
chown caterina /home/caterina
3. Alessandro spedisce il messaggio a Caterina (copiandolo nella sua home, Caterina deve aver attivato il
servizio SSH in precedenza):
scp ctext caterina@indirizzo Caterina:
4. Caterina cerca di scoprire la chiave usata da Alessandro per cifrare il messaggio
Ora provate a scoprire la chiave usata per cifrare il file di test bruteforce enc: è stato cifrato secondo la stessa
procedura precedentemente seguita da Alessandro. Incontrate delle difficoltà?
→
4
1.3
Modifica dei messaggi cifrati
Ora potete provare a modificare un messaggio cifrato, usando l’editor esadecimale hexedit:
hexedit ctext
(Ctrl+X per salvare ed uscire).
Formate gruppi di tre persone (diciamo Alessandro, Beatrice e Caterina) e procedete nel seguente modo:
1. Alessandro e Beatrice scelgono una chiave comune
2. Alessandro prepara un nuovo messaggio di testo contenente solo numeri decimali1 e lo cifra con l’algoritmo RC4 e il segreto condiviso con Beatrice
3. Alessandro passa poi il messaggio cifrato a Caterina che, prima di recapitarlo a Beatrice, proverà a
modificarlo (in pratica, Caterina avrà il ruolo di Man-in-the-Middle che non conosce la chiave comune)
4. Beatrice dovrà capire se il messaggio recapitatole da Caterina è stato modificato o meno
Cosa può fare Caterina per ingannare i due amici?
→
Cosa cambia usando AES-128-CBC al posto di RC4? (provate).
→
1.4
Uso degli algoritmi di cifratura a blocchi
Prendete in considerazione i tre file ecb*. I primi due contengono due possibili messaggi in chiaro, mentre il
terzo è la cifratura di uno primi due col seguente comando:
openssl enc -e -in ecb plain X -out ecb enc -K chiave -iv 0 -des-ecb
Riuscite a scoprire quale dei due messaggi è stato cifrato?
→
1.5
Prestazioni
Soffermiamoci ora a valutare il costo degli algoritmi crittografici in termini sia di tempo impiegato per le
operazioni crittografiche sia di quantità di dati addizionali introdotti.
Create alcuni file di dimensioni differenti; ad esempio 100 B, 10 kB, 1 MB e 100 MB. Per creare file di una
determinata lunghezza potete usare il comando:
openssl rand -out r.txt dimensione in byte
Ora compilate la Tabella 1 con i tempi necessari per cifrare i file con diversi algoritmi e diverse lunghezze di
chiave. Per valutare il tempo impiegato dalle operazioni di cifratura usate il comando time:
time stringa di comando openssl
1 Immaginate che il numero sia un codice di accesso o l’importo di un bonifico che Alessandro chiede a Beatrice di inviare a Caterina
5
Qual è la quantità significativa tra quelle riportate dal comando time?
→
Il tempo impiegato dall’operazione di decifratura per gli algoritmi in tabella sarà sensibilmente differente?
(provate)
100 B
10 kB
1 MB
100 MB
DES-CBC
DES-EDE3
RC4
AES-128-CBC
AES-128-IGE
AES-256-CBC
AES-256-IGE
Tabella 1: prestazioni di alcuni algoritmi di cifratura simmetrica.
Nota: OpenSSL include un comando per verificare le prestazioni degli algoritmi di cifratura supportati. Provate
ad eseguire il seguente comando:
openssl speed aes-128-cbc
Quali differenze ci sono tra l’uso del comando time e quello del comando speed per valutare le prestazioni di
un algoritmo crittografico?
→
2 Algoritmi di digest
2.1
Calcolare e verificare il digest di un messaggio
Create un messaggio di testo tipo “Questo e’ un messaggio di prova per il calcolo del digest!” in un file chiamato
msg e calcolate il suo digest usando gli algoritmi MD5, SHA1, SHA-256. Scegliete l’output in formato binario
e salvate il risultato nei file MD5dgst, SHA1dgst, e SHA256dgst. Scoprite la corretta stringa del comando
OpenSSL e scrivetela:
→
Ora provate a modificare il messaggio (ad esempio rimuovendo il “!” finale) ed a ricalcolarne il digest. Cosa si
può notare confrontando i due digest? (è consigliabile l’uso di un editor esadecimale)
Supponete ora di voler calcolare un digest su msg usando l’algoritmo AES usato negli esercizi precedenti: quale
schema potreste usare?
→
Confrontate le vostre idee con quanto fatto storicamente dalla funzione crypt di Linux:
man crypt
2.2
Collisioni
Proviamo ora a valutare la robustezza di un algoritmo di digest e quanto conta la sua lunghezza in bit presentando un esempio di algoritmo di hash “insicuro”.
6
Di seguito è presentato un estratto del codice C di un “Insecure Hash Algorithm” (IHA1). IHA1 fa semplicemente l’EX-OR bit a bit (un byte alla volta) del file e restituisce il risultato su 4 bit:
while ((xc=fgetc(file_in)) != EOF)
hash ˆ= xc;
printf ("iha1(%s) = %X\n", argv[1], hash % 16);
Il file iha1.c è presente nell’archivio contenente il materiale di supporto per questa esercitazione. Compilatelo
col seguente comando:
gcc iha1.c -o iha1.exe
Il file iha1.exe accetta come primo parametro da riga di comando il nome del file di cui calcolare il digest:
./iha1.exe file input
Create un file contenente il seguente testo: “Questo e’ un messaggio per provare la robustezza di un algoritmo
di digest” e calcolatene il digest usando IHA1.
Identificate una procedura per creare un altro messaggio che, elaborato come sopra, dia come risultato un digest
identico. Quante volte sarà necessario eseguire IHA1 in media?
→
Supponete di voler cercare una collisione arbitraria, cioè due messaggi che abbiano lo stesso digest (e non un
messaggio che abbia il digest uguale a quello di un altro messaggio fisso. Quanto dovrebbe essere lungo il
digest per richiedere mediamente lo stesso numero di tentativi impiegato nell’operazione precedente? Riuscite
ad immaginare una situazione in cui poter ricavare una collisione arbitraria risulti in una seria minaccia?
→
2.3
Applicazioni degli algoritmi di digest: keyed-digest
Supponiamo che Alessandro voglia generare il keyed-digest di un messaggio che vuole inviare a Beatrice.
Alessandro crea un file chiamato msg con un messaggio di testo tipo il seguente:
Questo e’ un messaggio di prova per la creazione di un keyed-digest!
e crea un file key in cui memorizza la chiave che utilizzerà per calcolare il keyed-digest.
Come può Alessandro usare il comando dgst di OpenSSL per calcolare un keyed-digest su msg? Cosa deve
conoscere Beatrice per verificarlo? Quali passi deve compiere Beatrice per verificarlo?
→
Descrivete due possibili applicazioni della funzione di keyed-digest costruita sopra.
→
Cercate adesso i comandi OpenSSL che permettano di calcolare un (particolare tipo di) keyed-digest. →
Come possiamo verificare il keyed-digest generato con il precedente comando OpenSSL?
7
Supponete ora di voler calcolare un keyed-digest su msg usando l’algoritmo AES usato negli esercizi precedenti:
quale schema potreste usare?
→
2.4
Applicazioni degli algoritmi di digest: integrità dei file
I tool sha1sum e hashdeep consentono di calcolare comodamente l’hash su uno o più file (il secondo processa
ricorsivamente i file contenuti in una directory con un o più algoritmi a scelta).
Create una directory, chiamatela tree, ed al suo interno un albero di sotto directory e file; per semplicità potete
utilizzare lo script di test gen tree.sh.
Scrivete qui di seguito il comando per calcolare il digest di tutti i file contenuti nella directory tree
→
e verificate con hashdeep -c sha1 -r -x -k hash list *
Formate ora delle coppie (diciamo Alessandro e Beatrice) e procedete come segue:
1. Alessandro si connette al PC di Beatrice via SSH e modifica alcuni file all’interno della directory tree;
2. Beatrice cerca di scoprire quali siano stati modificati.
Cosa può fare Alessandro per non farsi scoprire?
→
Quali accorgimenti dovrebbe adottare Beatrice per non essere imbrogliata? Pensatene almeno due.
→
2.5
Prestazioni
Ora provate a valutare, secondo la metodologia usata nell’Esercizio 1.5 per gli algoritmi di cifratura, il costo associato agli algoritmi di digest implementati da OpenSSL. Confrontate i risultati ottenuti con quelli
precedentemente calcolati per gli algoritmi di cifratura simmetrici e compilate la Tabella 2.
100 B
10 kB
1 MB
100 MB
MD5
SHA1
RMD160
SHA256
Tabella 2: tempo di elaborazione di alcuni algoritmi di digest.
8
3 Mettendo tutto assieme
Come si possono usare i comandi OpenSSL che avete sperimentato sinora per inviare ad una controparte un
documento di testo in modo riservato e tale che si possa verificarne l’integrità? Scrivete una possibile procedura.
9