89
Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 1 Appunti di Sicurezza nelle Comunicazioni AA 2007/2008

Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

  • Upload
    vuphuc

  • View
    222

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 1

Appunti di Sicurezza nelle Comunicazioni

AA 2007/2008

Page 2: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 2

LEZ. 01 - 26/09 Introduzione al Corso – Introduzione alla Sicurezza ............................................................... 5

Differenza tra Safety e Security ..................................................................................................................... 5

DEFINIZIONI ................................................................................................................................................... 5

Attacchi. ......................................................................................................................................................... 5

LEZ. 02 - 27/09 Introduzione alla Crittografia .................................................................................................. 6

PRINCIPIO DEL MINIMO PRIVILEGIO (PoLP). ................................................................................................. 6

La Crittografia ................................................................................................................................................ 7

Cifratura Simmetrica: .................................................................................................................................... 7

LEZ. 03 - 28/09 Introduzione alla Crittografia / Crittografia Classica ............................................................... 8

Cifratura a chiave Pubblica (PK) .................................................................................................................... 8

Digital Signature ............................................................................................................................................ 9

CRIPTOSYSTEM. ............................................................................................................................................. 9

LEZ. 04 – 03/10 Cenni di Teoria di Shannon / Cifrari a blocco e a flusso (parte 1) .......................................... 9

Cifrario a sostituzione: ................................................................................................................................... 9

Cifrario Affine: ............................................................................................................................................. 10

Vector affine cipher: .................................................................................................................................... 11

Permutation cipher: .................................................................................................................................... 11

Stream cipher: ............................................................................................................................................. 11

Cosa vuol dire Sicurezza?............................................................................................................................. 12

Definizione di Segretezza perfetta data da Shannon: ................................................................................. 12

One Time Pad: ............................................................................................................................................. 13

Cifrario a Blocco (Block Cipher). .................................................................................................................. 13

Cifrario a Flusso (Stream Cipher). ................................................................................................................ 13

Self Sinchronized Ciphers: ........................................................................................................................... 14

Sinchronous Ciphers: ................................................................................................................................... 14

LEZ. 05 – 04/10 Cifrari a Blocco e a Flusso (parte1) ....................................................................................... 15

DES (Data Encryption Standard). ................................................................................................................. 16

LEZ. 06 – 05/10 Cifrari a Blocco e a Flusso (parte2 – AES, Blowfish) .............................................................. 17

The AES Cipher – Rijndael. ........................................................................................................................... 18

AES su un’architettura a 32-bit .................................................................................................................... 21

Cifrario Blowfish. ......................................................................................................................................... 21

LEZ. 07 – 10/10 Cifrari a Blocco e a Flusso (parte2, RC4) / Modi operativi .................................................... 22

Inizializzazione. ............................................................................................................................................ 22

Page 3: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 3

Cifratura. ...................................................................................................................................................... 22

Decifratura. .................................................................................................................................................. 22

Modi Operativi. ............................................................................................................................................ 23

Padding e Modi Operativi a Blocco. ............................................................................................................ 23

Cipher Block Chaining (CBC). ....................................................................................................................... 23

Initial Vector (IV). ......................................................................................................................................... 24

Modi Operativi a Flusso. .............................................................................................................................. 24

Output FeedBack (OFB). .............................................................................................................................. 24

Cipher FeedBack (CFB). ................................................................................................................................ 25

Counter Mode (CTR). ................................................................................................................................... 25

Problemi dei modi operativi. ....................................................................................................................... 25

LEZ. 08 – 11/10 Hash ...................................................................................................................................... 25

Hash Crittografico. ....................................................................................................................................... 25

The Random Oracle Model. ......................................................................................................................... 26

Algoritmi Randomizzati. .............................................................................................................................. 27

Algoritmo di Las Vegas: ............................................................................................................................... 27

Oracle model agorithm for Pmg: FINDPREIMAGE(h,y,q). ........................................................................... 27

Oracle model agorithm for SPmg: FINDSECONDPREIMAGE(h,x,q). ............................................................ 27

Oracle model agorithm for Cls: FINDSECOLLISION(h,q) .............................................................................. 27

Provably Secure Hash Functions.................................................................................................................. 29

LEZ. 09 – 12/10 MAC....................................................................................................................................... 29

MAC (Message Authentication Code). ........................................................................................................ 29

Length Extension Attack: ............................................................................................................................. 30

Partial Collision Attack: ................................................................................................................................ 30

HMAC: .......................................................................................................................................................... 31

CBC – MAC. .................................................................................................................................................. 31

ESER. 01 – 17/10 Aspetti realizzativi della crittografia simmetrica ................................................................ 32

Link Encryption: ........................................................................................................................................... 33

End to end Encryption: ................................................................................................................................ 33

ESER. 02 – 18/10 – PRNG Crittografici ............................................................................................................. 35

ESER. 03 – 19/10 – Elementi di teoria dei numeri e algebra ........................................................................... 39

Complessità Computazionale: ..................................................................................................................... 39

LEZ. 10 – 25/10 – Ordine in un gruppo, CRT. Introduzione alla crittografia PK .............................................. 42

Introduzione alla crittografia PK .................................................................................................................. 44

Page 4: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 4

LEZ. 11 – 31/10 – Crittografia a Chiave Pubblica - PK (Public Key) - RSA........................................................ 45

RSA ............................................................................................................................................................... 46

LEZ. 12 – 02/11 – Generazione dei numeri primi e attacchi a RSA. ............................................................... 48

LEZ. 13 – 07/11 – Attacchi a RSA, Crittosistemi a chiave pubblica alternativi ad RSA. .................................. 51

Crittosistemi a chiave pubblica alternativi ad RSA. ..................................................................................... 53

Il logaritmo discreto .................................................................................................................................... 53

LEZ. 14 – 14/11 Crittosistemi a chiave pubblica alternativi ad RSA – ............................................................ 54

DL problem in ElGamal – Cenno alle ECC –Intro Firme Numeriche. ............................................................... 54

Forgiare una firma ....................................................................................................................................... 58

LEZ. 15 – 15/11 Firme Numeriche. ................................................................................................................ 58

LEZ. 16 – 16/11 (prima parte) - Firme Numeriche DSA e Protocolli di Autenticazione. ................................. 62

LEZ. 17 – 16/11 (seconda parte) - Protocolli di Autenticazione – Key Management. ..................................... 65

Il Disavowal Protocol ................................................................................................................................... 66

LEZ. 18 – 22/11 - Protocolli crittografici – Diffie-Hellman e sue varianti autenticate. .................................... 68

LEZ. 19 – 23/11 – Forward Secrecy in DH - Autenticazione. ........................................................................... 75

LEZ. 20 – 28/11 (prima parte)– Autenticazione: password – .......................................................................... 79

Protocolli di Autenticazione (Security Handshake). ........................................................................................ 79

Esempi di protocolli di autenticazione ........................................................................................................ 81

Protocollo Login-only con Secret Key. ......................................................................................................... 82

LEZ. 21 – 28/11 (seconda parte)– Protocolli di Autenticazione (Security Handshake). .................................. 83

Fine. ............................................................................................................ Errore. Il segnalibro non è definito.

Page 5: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 5

LEZ. 01 - 26/09 Introduzione al Corso – Introduzione alla Sicurezza

Differenza tra Safety e Security, la prima riguarda le persone, la seconda i dati o più in generale le cose. La sicurezza è tutto ciò che riguarda:

- Value: ciò che ho da proteggere; - Locks: i modi in cui lo proteggo; - Police & Courts: chi interviene in caso di attacco.

Nella Computer and Network Security, Locks sono i meccanismi di sicurezza (gli strumenti crittografici), mentre le locks keys, sono i meccanismi di autenticazione. I lucchetti di per se sono inutili se non fanno parte di un ben più ampio sistema di sicurezza. Quando definiamo ed implementiamo gli strumenti crittografici dobbiamo distinguere la Policy, che specifica gli obbiettivi da raggiungere, dai Mechanism, che sono delle procedure realizzative che utilizzano crittografia per espletare funzioni di sicurezza. Una volta definiti gli Assets (Value), il proprietario (Owner) ne definisce la Policy in modo da prevenire le Threats (minacce) che possono intervenire tramite degli attacchi. L’attacco è qualcosa che danneggia o usa impropriamente il bene (Value). Which Secutity? L’ideale sarebbe far sì che l’attacco costi di più di quanto possa rendere. DEFINIZIONI Network Security: misure atte a proteggere dati e transazioni durante la loro permanenza in una rete di computer. Security Attack: ogni azione che compromette la sicurezza dell’informazione. Security Mechanism: procedure specifiche designate per: Prevenire, Rivelare, Recuperare, eventuali attacchi. Security Service: servizio che migliora la sicurezza degli Assets utilizzando i meccanismi di sicurezza. I servizi di sicurezza si raggruppano in 5 maggiori categorie: . Authentication: assicurarsi che l’entità con cui si comunica sia quella voluta. . Access Control: prevenire un uso delle risorse non autorizzato. . Data Confidentiality: protezione di dati da una diffusione non autorizzata. . Data Integrity: garantisce che il dato ricevuto non sia stato modificato e che sia conforme all’originale. . Non-Repudiation: protezione contro la volontaria negazione da parte di una delle due entità attive nella comunicazione. È possibile individuare un protocollo di sicurezza a strati (Security Protocol Layer) così come il modello OSI di IP. Salendo (verso il lato applicativo) si effettua cifratura in periferia, scendendo (verso lo strato fisico) si effettua cifratura nei nodi di rete. Salendo è quindi più semplice e flessibile introdurre sicurezza esattamente nella misura e laddove è richiesta. Scendendo verso gli strati più bassi, e in maniera meno selettiva, tutto quello che passa verrà cifrato. Attacchi. È importante fare l’analisi delle minacce, inventariare i beni da proteggere. Chi sono le minacce? Quali sono le loro risorse? La Vulnerabilità è una debolezza, spesso un errore nel codice che può essere di tipo progettuale o realizzativo, e che viene sfruttato per portare avanti un attacco. L’Attacco è il metodo per sfruttare le vulnerabilità, portato avanti da un Threat che rappresenta qualcuno o qualcosa motivata a fare ciò. Gli attacchi compromettono:

Page 6: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 6

- La segretezza (o confidenzialità), causando una diffusione impropria dell’informazione. - L’integrità, causando un’alterazione impropria dell’informazione. - La disponibilità, se causano dei fuori servizio.

Gli attacchi possono essere: Passivi: (ascolto senza intervento) infrangono servizi di sicurezza come la riservatezza e la confidenzialità, ma non l‘autenticazione. Attivi: se l’attaccante interviene attivamente sullo stream di info modificandolo, spacciandosi per una delle due entità, ripetendo messaggi precedenti, modificando messaggi in transito, o negando il servizio. Gli attacchi passivi non sono rivelabili, non si può fare Detection e quindi Reaction, a meno di un errore dell’attaccante.

LEZ. 02 - 27/09 Introduzione alla Crittografia

Esempi di attacchi alla sicurezza sono:

- Interruzione: attacco alla disponibilità. - Intercettazione: attacco alla confidenzialità (Evedropping: EVE). - Modifica: attacco alla integrità (Man in the Middle: MALLORY). - Fabricazione: attacco all’autenticità.

Un modello di Interazione Sicura (Security Interaction Model) è il seguente:

Alice e Bob sono le entità interessate, l’Opponent è l’avversario motivato all’attacco, Trent sono le terze parti fidate, il canale di comunicazione è la risorsa di trasferimento, S sono le trasformazioni legate alla sicurezza, trasformano l’informazione prima di trasmetterla. L’uso di un modello del genere richiede: l’implementazione delle trasformazioni legate alla sicurezza; la generazione di informazioni di sicurezza (le chiavi) usate dagli algoritmi; implementazione di metodi per la distribuzione e condivisione delle chiavi (problema principale); specifica di protocolli che abilitino i principali user di trasformazioni e chiavi di un servizio o meccanismo di sicurezza. PRINCIPIO DEL MINIMO PRIVILEGIO (PoLP). Ogni applicazione ed ogni utente di un sistema, dovrebbero operare usando il minimo set di privilegi necessari a completare il lavoro. Come corollario si usa il: Failsafe Defaults, ogni accesso è negato senza una esplicita richiesta. Ma anche il Separation Of Privileges, secondo cui ogni meccanismo crittografico deve richiedere una chiave propria, ciò però va mediato con la fattibilità, il vero problema è generare congiuntamente la

Canale S S

Page 7: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 7

chiave tra le parti. La soluzione è una chiave a lungo termine che permetta di generare le sottochiavi a breve termine. Parlando di crittografia bisogna affermare che la sicurezza non è misurabile! La complessità poi è il suo peggior nemico: KISS Principle (Keep It Simple, Stupid!); un sistema semplice non è necessariamente un piccolo sistema, �MODULARIZZAZIONE ! La soluzione sta nel realizzare il sistema in modo modulare, in cui ogni blocco sia indipendente dagli altri ma con semplici interfacce tra le singole parti. La Crittografia è l’arte e la scienza di criptare, codificare, includendo regole di controllo come l’Autenticazione, la Firma Digitale, il Controllo d’accesso. La crittografia, come i lucchetti, è di per se inutile se non fa parte di un più completo sistema di sicurezza, anche se essa ne rappresenta la parte più critica. Raramente la crittografia però è l’anello debole del sistema, ma essa deve funzionare, specialmente nei sistemi che hanno altre debolezze. Un sistema di sicurezza è tanto robusto quanto lo è il suo anello più debole. Bisogna pensare che l’Opponent sia intelligente, e che attaccherà il sistema nel suo punto più debole. Il sistema di sicurezza si confronta con Opponent attivi, di cui non si conosce l’identità, le conoscenze, gli obbiettivi e il momento in cui attaccheranno. Chi attacca dovrà trovare solo un singolo punto debole, mentre chi protegge deve controllare ogni area del sistema. Si protegge quindi secondo il Paranoia Model. La sicurezza è sempre un misto di Prevenzione, Rivelazione, Risposta, il ruolo della crittografia è la prevenzione. CIFRARE vuol dire modificare l’informazione in modo che sia correttamente ricevibile dai destinatari legittimi, ma sia del tutto inservibile a qualsiasi altra terza parte. Cifratura Simmetrica:

Alice ha un plaintext m da mandare a Bob; usando una KC (secret key) e una funzione di cifrature E(k,x) ottiene il ciphertext c che viene decriptato da Bob tramite la funzione di decifratura D(k,x) e la stessa chiave segreta KC. => E’ necessario che E sia invertibile i.e. D=E-1, il problema maggiore rimane quindi la Distribuzione della Chiave. La sicurezza di un sistema di cifratura deve dipendere solo dalla segretezza della chiave e non

degli algoritmi di cifratura.

Page 8: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 8

LEZ. 03 - 28/09 Introduzione alla Crittografia / Crittografia Classica

Cosa si vuol fare? Permettere a Bob di poter dire che il messaggio è proprio conforme a quello di Alice (Integrity) e che è proprio Alice che lo ha mandato (Identity). La risposta dell’Autenticazione sarà semplicemente Yes or No.

Alice calcola il Message Authentication Code (MAC) a utilizzando la sua chiave segreta Ka e il plaintext m � a=h(Ka,m) tramite il Crittographic Hash Algoritm, e manda a Bob m,a. Bob calcola a’=h(Ka,m) e confronta a’ con a, se a’=a Bob accetta m. L’autenticatore h(K,x) non è necessariamente invertibile, e per evitare overhead voglio che sia piccolo. L’Opponent può effettuare Forging (forgiatura) generare una coppia a’,m’ valida, cioè con a’ autenticatore corretto di m’, ma con m’ messaggio che non è mai stato autenticato da Alice. L’obbiettivo del MAC è rendere computazionalmente infattibile l’operazione di Forging. Il MAC non garantisce la Confidenzialità, ma la Autenticità e Integrità del messaggio. Oscar (the Opponent), oltre a modificare, può ripetere, cancellare, ritardare, o alterare l’ordine dei messaggi. Cifratura a chiave Pubblica (PK)

Alice calcola c=E(PKB,m) testo cifrato con la chiave pubblica di Bob. Bob usa D=E-1 che è facilmente calcolabile, anche da Oscar, ma essendo parametrica ho bisogno della chiave segreta SKB di Bob per decifrare e recuperare m. Il problema è: sono sicuro che Alice abbia proprio la PK di Bob? Public Key Authentication.

Page 9: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 9

Digital Signature: Autenticazione fatta con paradigma a chiave pubblica.

Alice calcola s=g(SKA,m) con la sua SKA e l’algoritmo di firma digitale g(SK,x) e manda a Bob s,m. Bob vi applica un algoritmo di verifica v(PKA,m,s) usando la chiave pubblica di Alice, se il controllo ha successo accetta m. Livelli di Sicurezza: Dipendono dalla complessità delle tecnologie. Ogni sistema crittografico può essere attaccato con successo, il punto è con quale complessità computazionale? Lo sforzo di un attacco è in genere specificato dal “# passi elementari” (Steps) da effettuare. Un desiderabile livello, per il progetto di un sistema affidabile, dovrebbe essere 2128 steps. CRIPTOSYSTEM. Un Criptosystem è rappresentato dalla 5-pla (P,C,K,E,D) dove:

- P: insieme finito dei possibili plaintext (dominio della funzione di cifratura);

- C: insieme finito dei possibili ciphertext (codominio della funzione di cifratura);

- K: Keyspace, insieme finito delle possibili chiavi. Si passa da P a C usando un elemento k di K.

, e il corrispondente t.c. e

ed sono tali che .

Attacco a Forza bruta: conosco una coppia di pj,cj , provo tutte le possibili chiavi, quella chiave che a pj mi fa corrispondere proprio il mio cj è sicuramente la chiave buona.

LEZ. 04 – 03/10 Cenni di Teoria di Shannon / Cifrari a blocco e a flusso (parte 1)

Facciamo un excursus di codici storici che ci permettono di far emergere un paio di idee fondamentali, maturate nel corso degli anni, che sono oggi alla base di progetto e utilizzazione di qualunque cifrante o algoritmo di cifratura. Cifrario a sostituzione: ho un alfabeto, definisco un mapping che mappa l’alfabeto con se stesso, il mapping che definisco, cioè la corrispondenza biunivoca, è la chiave stessa, e quindi data una stringa di caratteri di quest’alfabeto, la trasformo in un’altra stringa attraverso questa funzione biunivoca. Poiché conserva la struttura intrinseca del testo (qualora ci sia una struttura), esso risulta perfettamente attaccabile perfino con attacco ciphertext only, in cui ho soltanto il testo cifrato e ricostruisco il testo in chiaro.

Page 10: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 10

Cifrario Affine: è un cifrario scalare, come dire che il testo in chiaro e il testo cifrato appartengono ad un insieme di 26 elementi, rappresentati da numeri interi da 0 a 25, in realtà erano le lettere dell’alfabeto da A a Z.

La chiave in questo caso è una coppia di numeri interi da 0 a 25, con la proprietà che valga questo:

K={(a,b) Є Z26 x Z26 : gcd(a,26)=1} posto gcd(x,y) (massimo comune divisore: intero più grande che è divisore (essere divisore vuol dire che la divisione tra

l’intero dato e il divisore da resto zero) contemporaneamente dei due interi x e y) chiedere che gcd(a,26)=1, vuol dire che a e 26 sono primi tra loro, ad esempio se a=4 il gcd(4,26)=2 condizione falsa, se a=9, tra 9 e 26, è 1. Detto questo la funzione di cifratura è la seguente, ho una trasformazione affine del testo cifrato, il testo cifrato è un numero tra 0 e 25, ed io faccio questo calcolo:

eK(x)=(ax+b) mod 26 nel quale ho fatto il mod 26del prodotto di numeri interi, ho cioè diviso per 26 e ne ho preso il resto, ottenendo un numero tra 0 e 25, e quindi un crittotesto. Per produrre un testo cifrato occorre eseguire un operazione di codifica dei dati da cifrare, in un formato adatto alla cifrante, in questo caso un numero intero tra 0 e 25. La condizione gcd(a,26)=1 serve a garantire che esista a-1 cioè che si possa scrivere l’inversa. Dire che un numero è l’inverso dell’altro vuol dire che il loro prodotto, mod 26 è pari ad 1: 3 è l’inverso di 9 poiché (3*9)mod26=1. Perché questo codice non serve a niente, innanzitutto qual è la chiave, sono i numeri a e b che dovrebbero rimanere segreti e che sono in numero inferiore a 26*26, perché abbiamo tolto su a tutti i numeri pari, quindi ¼ di 26*26, ma il problema strutturale è che se io conosco due coppie testo in chiaro testo cifrato, quindi un attacco di tipo non-plaintext (cioè conosco due testi cifrati corrispondenti a due testi in chiaro, non gli ho scelti io, li conosco) e sono così fortunato che i due testi in chiaro soddisfano questa proprietà: gcd(x1-x2,26)=1, posso scrivere un sistema del tipo:

In cui y1,y2 (testi cifrati), x1,x2 (testi in chiaro) sono i termini noti, a e b (key) sono le incognite. Tale sistema è lineare ed è risolvibile se la matrice dei coefficienti è invertibile, ma questo ci è garantito

Page 11: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 11

dalla condizione sopra: gcd(x1-x2,26)=1; posso quindi, conoscendo due coppie (x , y) risalire alla chiave risolvendo questo sistema. Vector affine cipher: potrei risolvere il problema riscrivendo questo criptosystem utilizzando però P e C appartenenti al prodotto cartesiano m volte di Z26 --> Z26m cioè una m-pla di lettere con m che può essere pure 100.

La chiave ora è rappresentata da una matrice A e da un vettore b tali che A è prima con 26

K={(A,b) : gcd(det(A),26)=1} che è la condizione per poter invertire A nell’aritmetica modulare: A-1 e t.c. (AA-1)mod26=I, matrice identità. Scrivo allora le equazioni come prima:

Le chiavi in questo caso sono m*m elementi di A, più m elementi di b, scegliendo m grande posso farle robuste. Purtroppo vale lo stesso attacco di prima, se conosco, questa volta non 2, ma più coppie, posso scrivere in definitiva un sistema lineare, quando ho m+1 equazioni la soluzione sarà univoca. Il motivo per cui questi codici soccombono ad attacchi non-plaintext è che creano un legame riconducibile ad equazioni lineari tra testo in chiaro e testo cifrato. La non linearità è una condizione

necessaria per ogni cifrario. Un cifrario privo di non linearità è da buttare. Permutation cipher: Invece di fare una sostituzione prendo le lettere del testo in chiaro e le mescolo tutte secondo una regola nota al destinatario

E’ un caso particolare del cifrario visto prima, con b=0 e A matrice identità permutata; rientra nei casi di codici lineari quindi risulta rompibile. Stream cipher:

è definito sempre dalla 5-pla (P,C,K,E,D) ma con qualcosa in più, un alfabeto del Keystream L cioè del flusso di chiavi, e una funzione generatrice del keystream g che prende in input la chiave segreta k appartenente a K e genera una stringa potenzialmente infinita di valori chiamato keystream.

Che ci si fa con il keystream? Per ogni valore z del keystream esiste una funzione di cifratura e la corrispondente funzione una inversa dell’altra. Un esempio pratico è l’LFSR (Linear Feedback Shift Register).

Page 12: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 12

L’idea è: ho una macchinetta g che prende in input k e restituisce la sequenza z, dopodiché il modo di cifrare è il seguente, supponendo di lavorare con i bit, la cifrante prende in input il bitstream, cioè i bit del testo in chiaro, e li mette in XOR (somma modulo 2: da 1 se gli elementi sono diversi, 0 se sono uguali) con i bit del keystream, chi riceve il testo cifrato lo prende e lo mette in XOR sempre con lo stesso keystream (la

funzione inversa dell’XOR e sempre la XOR); tutto si regge sul fatto che tutti e due stanno usando lo stesso keystream, la stessa macchinetta inizializzata allo stesso modo, ecco qui la chiave segreta. È necessario che la Feedback Function sia una funzione non lineare, altrimenti potrei osservare un certo numero di keystream e ottenere la chiave iniziale.

Cosa vuol dire Sicurezza? Ci sono definizioni precise, si parla innanzitutto di:

- Sicurezza Incondizionata: è quella vera, è indipendentemente da quante risorse di tempo e di calcolo io dispongo, la cifratura non può essere rotta.

- Sicurezza Condizionata: - Sicurezza Computazionale: dato un certo limite sul tempo e sulla capacità di calcolo che ha l’attaccante, si può dimostrare che esso non potrà portare a termine il suo attacco. - Sicurezza dimostrabile: cosa si dimostra? Si dimostra che poter attaccare l’algoritmo in esame con un determinato modello di attacco, equivale a risolvere un altro problema molto ben noto e ben studiato e che si ritiene difficile, cioè risolvere A equivale a risolvere B (che sappiamo non risolvibile) quindi A è Provable Secure.

Definizione di Segretezza perfetta data da Shannon: con riferimento ad un cifrario, supponiamo che esista una misura di probabilità definita sull’insieme dei testi in chiaro e sull’insieme delle chiavi, allora questo induce una misura di probabilità sull’insieme dei testi cifrati

Dove C(k) è l’insieme di tutti i testi cifrati prodotti con una fissata chiave k, è l’immagine dell’insieme X attraverso la funzione ek parametrica di k. Dopodiché la Segretezza Perfetta è definita così: un crittosistema ha segretezza perfetta se la probabilità a posteriori sul testo in chiaro x una volta osservato un testo cifrato y, è identica alla probabilità a priori sul testo in chiaro x. Osservando y, non ho appreso niente di più su x di quanto già sapevo a priori.

Come ottengo ciò? Innanzitutto Shannon ci dice che per ottenere ciò devo avere un numero di chiavi superiore al numero dei testi in chiaro Perfect secrecy implies |K|≥|P|.

Assumiamo che i testi cifrati abbiano tutti probabilità positiva, in quanto se ce ne fossero con probabilità nulla li eliminiamo e ridefiniamo C, quindi hanno tutti probabilità positiva. Se un crittosistema ha segretezza perfetta ho Pr{X=x|Y=y}=Pr{X=x} da cui secondo Bayes risulta positiva la seguente Pr{Y=y|X=x}=Pr{Y=y}>0 che mi dice che dato un testo in chiaro, la probabilità di vedere un

Page 13: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 13

testo cifrato è positiva, quindi dato un testo in chiaro esiste sempre una chiave k per cui ek(x)=y poiché la funzione è biunivoca i k devono essere tra loro distinti, |K|≥|C| cioè per ogni testo cifrato c’è una chiave che lo produce, poi |C|≥|P|è necessario poiché garantisce l’invertibilità della cifrante ci devono essere per forza più testi cifrati, non meno di quanti sono i testi in chiaro altrimenti non posso fare decifratura. Dalle ultime due discende quindi che per poter fare segretezza perfetta deve essere |K|≥|P| tante chiavi quanti sono i testi in chiaro. Mettendoci in queste condizioni Shannon dice che: partendo dal fatto che ne servono di più, affermiamo che non c’è motivo di avere più chiavi del numero di testi in chiaro, quindi le prendiamo uguali. Dato allora un crittosistema con |K|=|C|=|P|, esso avrà segretezza perfetta se scegliamo le chiavi a caso (con uguale probabilità ), e se usiamo una sola chiave per ogni testo in chiaro, cioè esiste

una sola chiave che da un testo i chiaro produce un testo cifrato One Time Key. One Time Pad: dato un vettore di n arbitrario bit, la teoria ci dice che dobbiamo avere uno spazio delle chiavi almeno uguale allo spazio dei testi in chiaro che in questo caso sono 2n, quindi per avere lo spazio delle chiavi della stessa dimensione devo prendere chiavi lunghe n. La funzione cifrante sarà

ek(x)=dk(x)=(x+k) mod 2 faccio l’XOR bit a bit tra il testo in chiaro e il keystream di n bit. La segretezza è data dal fatto che io ho un numero di bit di chiave pari al numero di bit da cifrare, che sono scelti a caso. Questo in effetti è il One Time Pad, è un codice Unconditional Secure, non c’è modo di attaccarlo in quanto il keystream è una sequenza puramente random, qualunque sia x, y sarà puramente random, non riconoscibile. Il limite sta nel fatto che siccome i keybit vanno usati una sola volta, i bit di chiave non sono comprimibili, l’informazione sta su tutti gli n bit, a differenza dell’LFSR in cui l’informazione stava solo sulla chiave iniziale. Il difetto sta nel fatto che per trasmettere n bit sicuri, io devo aver prima condiviso n bit di chiave in modo sicuro. Rinunciando alla sicurezza perfetta, ottenibile solo con OTP, realizzo dei cifrari che utilizzano chiavi di lunghezza inferiore al numero di bit che voglio trasmettere: Cifrari a Blocco e a Flusso. Cifrario a Blocco (Block Cipher). È un algoritmo che trasforma in maniera biunivoca (per garantire l’invertibilità) stringhe di bit di lunghezza fissa, in stringhe di bit di lunghezza fissa non inferiore alla precedente. Matematicamente è un mapping dell’insieme An su se stesso. A è l’insieme dei bit A={0,1} and n=64÷128 e An e il prodotto cartesiano n volte di A cioè l’insieme delle stringhe binarie di n bit. La funzione di cifratura non è altro che una funzione che associa ad una stringa di n bit un’altra stringa di n bit, quindi non è altro che una permutazione dell’insieme An. Come si può ottenere? Basta elencare tutte le stringhe su di una colonna, poi le si permutano e si mettono su di un’altra colonna e così via. Stringhe sulla stessa riga sono quelle corrispondenti, e questo è un cifrario a blocco. Si prende l’elenco di tutte le possibili stringhe da un lato, l’elenco delle possibili stringhe permutato, e stringhe associate sono in corrispondenza biunivoca, se si legge da sin a dest è cifratura, mentre leggendo da dest a sin è decifratura. --> Sostituzione Monoalfabetica. Il numero di possibili permutazioni è pari alla cardinalità dell’insieme cioè (2n)! o meglio (An)! , che è poi lo spazio delle chiavi. Non è possibile però memorizzare una mole di dati così grande (nel caso di blocchi da 64 bit avrei bisogno di 16 milioni di TB), allora a costo di perdere e quindi ridurre questo spazio di chiavi, si costruisce un algoritmo parametrizzato dalla chiave, che mappa univocamente stringhe binarie in un’altra stringa binaria, quindi nell’insieme di tutte le possibili permutazioni si sceglie un sottoinsieme realizzabile con un dato algoritmo in ingresso al quale do anche una chiave, se la chiave è lunga 56 bit vuol dire che di tutte le possibili permutazioni ne sta scegliendo 256, e quale di queste sceglierò dipende dalla chiave scelta. Cifrario a Flusso (Stream Cipher). Cifrario in cui dalla chiave e da una regola per generare un flusso binario, si produce un keystream, poi mette in XOR bit a bit o byte a byte e produce il testo cifrato, e allo stesso modo recupera il testo in chiaro.

Page 14: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 14

Gli Stream Ciphers si dividono in Autosincronizzanti (Self Sinchronized Ciphers) e Sincroni (Sinchronous Ciphers). I Sincroni sono in grado di produrre il keystream a prescindere dal testo in chiaro, mentre i primi producono il keystream utilizzando l’uscita della cifrante. Com’è fatto un Keystream Generator, se volessimo il One Time Pad, il keystream generator dovrebbe essere un generatore di bit casuali. Per cifrare n bit lui mi produce n bit casuali e così io realizzo il One Time Pad ma questo vorrebbe dire trasmettere una chiave di n bit. Il Keystream generator invece ha uno stato interno, un algoritmo che calcola, a partire dalla chiave e dallo stato interno attuale, il prossimo valore dello stato.

Per uno che non conosce la chiave, ciò che esce deve apparire come una sequenza scorrelata e non predicibile. Self Sinchronized Ciphers: come funziona, all’inizio carico nel registro interno gli n bit della chiave e con quelli inizio a cifrare, entra il testo in chiaro, lo metto in XOR con il keystream, esce il testo cifrato, che oltre ad essere inviato viene re immesso (a blocchi di n bit) nello stato interno e viene utilizzato per produrre il keystream.

Per decifrare cosa faccio: arriva il testo cifrato, lo si manda all’ingresso di uno stesso algoritmo inizializzato allo stesso modo, questo è fondamentale, il quale inizia a produrmi lo stesso keystream, se inizializzato allo stesso modo. Sinchronous Ciphers: nel caso sincrono invece ho una chiave, che eventualmente entra anche nello

stato iniziale, e calcola il keystream indipendentemente dal testo in chiaro e dal testo cifrato, per esempio potrebbe farlo anche prima offline, questo oggetto quindi dovrebbe funzionare come un generatore di numeri casuali non predicibili idealmente. Il keystreamer ce l’ha sia chi cifra che ci decifra e lo inizializzano allo stesso modo poiché hanno la stessa chiave. Chi decifra recupererà il testo in chiaro a patto che si abbia sincronismo con il testo cifrato ricevuto. Se chi riceve perde il passo con il testo cifrato, cioè si disallinea, non ha modo di recuperare il sincronismo, non se ne rende

conto, tira fuori dei bit di testo in chiaro che saranno dichiarati corrotti da qualche altro meccanismo di correzione. In questo cifrario è fondamentale mettere nel crittotesto l’informazione necessaria ad allineare i due. Ciò non avviene nel cifrario auto sincronizzante poiché il meccanismo è pilotato proprio dai bit che riceve. Se altero o cancello uno dei bit che ricevo avrò un errore all’uscita dei cifrari, ma nel cifrario Autosincronizzante l’errore rimane per il tempo in cui lo stato interno non viene rigenerato dagli altri

Page 15: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 15

n bit del crittotesto quindi in uscita avrò n bit errati e non di più, nel cifrario Sincrono invece l’errore si avrà solo su quel bit, quindi non c’è propagazione d’errore; questo solo se mantengo il sincronismo, se perdo il sincronismo non ho più modo di recuperarlo. Pro e Contro. I cifrari a flusso si prestano meglio per un’implementazione molto efficiente in hardware, mentre i cifrari a blocco per realizzazioni software perché le architetture software funzionano per lo più con blocchi di dati di lunghezza fissa.

LEZ. 05 – 04/10 Cifrari a Blocco e a Flusso (parte1)

L’esempio storicamente più significativo di cifrario a blocco è il DES (Data Encryption Standard) nato negli anni ’70, il cosiddetto Cifrario di Feistel. Cosa deve fare un cifrario come obbiettivo ultimo, approssimare o al limite ottenere segretezza perfetta nel senso introdotto da Shannon. Come si fa in pratica questo? 1) introducendo trasformazioni non lineari e di sostituzione che creino relazioni complesse tra chiavi e testo cifrato, 2) distruggendo la struttura statistica del teso in chiaro in ingresso attraverso permutazioni. Tutto ciò però va fatto utilizzando operazioni base molto semplici da realizzare, eventualmente ripetendole. Come idea base si definisce un singolo blocco di istruzioni che si chiama Round e poi applichiamo al testo in chiaro che entra, e successivamente ai testi via via elaborati, ripetutamente il medesimo round. Il round altro non è che un insieme di sostituzioni e permutazioni. L’applicazione di un singolo round non porta sicurezza, ma l’applicazione ripetuta di più round porterà ad un cifrario sicuro, mantenendo però semplice la struttura del singolo round. Feistel si è limitato a fare un loop base: in ingresso si ha una stringa binaria che rappresenta un blocco

(stiamo parlando di un cifrario a blocco) il blocco viene diviso in due parti uguali, la metà sinistra contiene i bit più significativi, la metà destra quelli meno significativi. Al passo i-mo (trasformazione della stringa i-1 nella stringa i) la parte Ri-1 viene manda così com’è al passo successivo come parte Li, mentre la parte Li-1 viene mandata in XOR con il risultato di una trasformazione, parametrizzata dalla chiave Ki, della parte destra Ri-1. In questo singolo passo si evince la presenza della permutazione, della trasformazione e dell’influenza della chiave. Una trasformazione così (singolo round) di per sé non può fare da cifrario perché ci sono almeno n/2 bit in chiaro privi di trasformazione, cosa risolvibile infatti applicando

ripetutamente il round. Ci si accorge poi che la trasformazione F può non essere invertibile, in più la stessa struttura utilizzata per cifrare, può essere utilizzata per decifrare, a patto però di mettere in ingresso correttamente la sequenza del ciphertext. Tipicamente le Ki sono stringhe di chiave di 64/128 bit e il pedice i suggerisce che ogni round cambiano. Questo schema di Feistel prevede la presenza di un altro algoritmo di generazione delle sottochiavi (Subkeys) Ki a partire dalla chiave K. Quest’algoritmo collaterale si chiama Keyschedule, che non è indispensabile in un cifrario a blocchi. In fase di decifratura lo schema utilizzato è lo stesso basta invertire l’ordine di inserimento delle chiavi, al round 0 andrà inserita la sottochiave KM.

Page 16: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 16

DES (Data Encryption Standard). È un cifrario a blocco che utilizza blocchi di 64 bit, dimensione scelta per mantenere limitata la complessità del singolo blocco, e per le architetture di calcolo disponibili. La chiave è lunga 56 bit, in

realtà è lunga 64 bit, ma ogni byte ho un bit di parità quindi i bit utili della chiave sono 56. L’unica vera debolezza del DES è dovuta alla scelta della chiave troppo corta, infatti ciò che rompe il DES è proprio l’attacco a forza bruta divenuto oggigiorno possibile per i 56 bit della sua chiave. Lo schema del DES prevede una trasformazione iniziale, poi successivi 16 round accanto ai quali c’è il Keyschedule che prende in ingresso i 64 bit di chiave, che sono in realtà 56, dai quali produce poi via via i 48 bit di sottochiave. Come viene fatto in dettaglio tutto questo. Entra il testo in chiaro, per prima cosa viene fatta una permutazione

iniziale IP Initial Permutation che prende i 64 bit e li rimescola secondo una corrispondenza biunivoca definita nello standard. Dopodiché divido i 64 bit in 32 MSB e 32 LSB e comincio il giro nel Feistel loop.

Il blocco che realizza la funzione f ha come input i 32 bit meno significativi del plaintext, più i 48 bit della sottochiave. Prima di tutto si esegue una funzione di espansione (E) dei 32 bit in 48, riscrivendo la metà dei bit due volte, risultando una sorta di permutazione e ripetizione. Questi bit vengono messi in XOR con la sottochiave (miscelamento con l’info segreta) ed in uscita ritroviamo 48 bit che vengono divisi in 8 blocchi da 6 bit ciascuno dei quali, individuando 26=64 alternative, indirizza una tabellina a 64 posizioni, una Look up table. In ognuna delle quali (64 posizioni) c’è scritto un numero da 0 e 15 rappresentato da 4 bit. In uscita da ogni S-box ottengo quindi 4 bit, che complessivamente sono 32;

successivamente li permuto, e quello che esce sono i 32 bit in uscita dalla funzione. È semplice notare come la funzione esegua al suo interno delle operazioni elementari come permutazioni e trasformazioni non lineari, come ci aspettavamo. Le S-box rappresentano 8 funzioni differenti, e i valori che contengono rappresentano proprio i valori delle funzioni. Esse sono state scelte e pubblicate con lo standard, quello che non è stato mai pubblicato sono i criteri con i quali sono state scelte. Il keyschedule funziona in questo modo, arriva la chiave a 56 bit che viene divisa in 28 bit e 28 bit, entrambi subiscono uno shift circolare (chiuso) a sinistra, successivamente subiscono una compressione e

Page 17: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 17

permutazione, cioè vengono cambiati di ordine e ne escono solo 48 dei 56, infine le due metà costituiscono l’input del successivo stadio. Come si fa a misurare la bontà di un cifrario? Secondo Shannon un cifrario dovrebbe essere deterministico ed invertibile, tale che prendendo in ingresso un testo in chiaro con una data chiave, restituisca in uscita una risposta che appare come casuale; osservando in pratica il testo in chiaro e quello cifrato, il tutto deve apparire come un generatore di stringhe casuali, non deve esserci nessun nesso tra in due testi. Un modo per vedere quanto ci si avvicini a ciò è prendere una stringa di bit e cifrarla, poi prendere la medesima stringa, cambiarne un solo bit e cifrarla di nuovo, e vedere quanti bit del testo cifrato sono cambiati. Ripetendo questo test su tanti testi in chiaro, in media un buon cifrario dovrebbe cambiare la metà dei bit; se cambiano tutti è un male poiché si ha correlazione tra le stringhe del ciphertext. La macchina cifrante DES comunque è utilizzabile, in che modo: 56 bit di chiave sono troppo pochi, ok, allora bisogna aumentare la chiave, come si fa? Lo utilizzo più volte il DES. Prendo il testo in chiaro, lo cifro con il DES, l’uscita la cifro di nuovo col DES, e se uso, per queste due cifranti in cascata, chiavi diverse, da 56 bit passo a 112 bit che sono validi oggigiorno. Quello che è stato definito è il cosiddetto Triple DES

Che tipicamente viene usato nella configurazione EDE (Encryption Decryption Encryption), che risulta compatibile all’indietro con chi usa il DES semplice. Infatti usando la configurazione EDE come illustrato sopra con le relative chiavi K1 K2, la chiave risultante sarà una chiave a 112 bit, per la quale non sono stati trovati attacchi pratici di natura cripto analitica, l’unico attacco che rimane è l’attacco a Forza Bruta che però risulta inefficace per una chiave a 112 bit. Comunicando con uno che usa solo il DES semplice, per essere compatibile basta mettere K2=K1, in questo modo cosa succede: cifro con K1, decifro con K1 quindi non ho fatto niente, infine cifro con K1 quindi riesco a parlare anche con uno che abbia soltanto il DES semplice. Perché il Triple DES e non il Double DES? C’è un problema di base, se uno usa il DES due volte, ma in generale se si usa qualsiasi cifrario due volte, non migliora la sicurezza contro un attacco a forza bruta rispetto ad usarlo una volta sola. Nel caso del DES ad esempio se la complessità dell’attacco è 256 passi nel caso semplice, nel caso di un doppio DES diventa 257 si può pensare infatti ad un attacco definito Meet in the middle. Tale attacco si basa sul fatto che se si fa una doppia cifratura con due chiavi K1 K2, chiamando x il risultato intermedio, l’attacco parte ovviamente dalla conoscenza di un plaintext e di un ciphertext. Io so che X = EK1[P] = DK2[C], cioè il risultato intermedio è uguale alla cifratura di P con chiave K1 e alla decifratura di C con chiave K2. Provo ordinatamente tutte le chiavi e le ordino rispetto ad x in una tabella che avrà dimensioni di 256, sia per K1 che per K2, confrontando le due tabelle poi troverò un elemento comune che corrisponderà ai due valori delle chiavi che ha generato quella coppia di testo in chiaro e testo cifrato.

LEZ. 06 – 05/10 Cifrari a Blocco e a Flusso (parte2 – AES, Blowfish)

Nel corso degli anni ’90 quindi, giunti alla soluzione della inadeguatezza del DES, si è aperta la questione di definire nuovi algoritmi crittografici. Il NIST nel 1997 ha promosso lo sviluppo di un nuovo standard, promuovendo un bando di gara pubblico internazionale in cui si specificavano i criteri richiesti per questo nuovo standard, l’AES (Advanced Encryption Standard). I criteri presi in esame sono abbastanza ovvi:

Page 18: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 18

- Sicurezza - Costo (nel senso della complessità dell’algoritmo) - Caratteristiche delle implementazioni sw (per esempio resistenza ad attacchi collaterali)

Successivamente ne sono stati esposti altri più raffinati, quali: - Resistenza ad attacchi collaterali - Facilità di implementazione sia in hw che in sw - Capacità di adattarsi ad ambienti con limitate risorse di calcolo (SmartCard) - Flessibilità parametrica (possibilità di modificare i bit di chiave)

Uno dei 5 finalisti di questo bando di gara fu il progetto Belga Rijndael, il cui cifrario AES aveva le seguenti caratteristiche. The AES Cipher – Rijndael. Innanzitutto oltre ad avere una struttura molto elegante dal punto di vista matematico, prevedeva dettagli come la possibilità di implementazione su processori a 8 bit e a 32 bit. Lo standard prevede che la dimensione della chiave possa essere 128 – 192 o 256 bit, e corrispondentemente il Plaintext Block Size è sempre fisso a 128 bit, mentre cambia il numero di round.

Cambiare il numero di round vuol dire cambiare un parametro, ma non mi aumenta di molto la complessità hw o sw. Analizzando la versione con chiave a 128 bit, il numero di round è pari a 10, come funziona l’algoritmo. In ogni round viene modificato lo stato, quindi l’algoritmo è basato sull’evoluzione dello stato interno, il blocco, che è composto da 128 bit, precisamente 4 parole da 32 bit. Inizialmente lo stato interno è inizializzato con il blocco di plaintext, ad ogni round questo blocco viene modificato, fino all’ultimo round che diviene il blocco di 128 bit di testo cifrato. Ad ogni round vengono eseguite 4 operazioni:

- Sostituzione non lineare byte per byte (SubBytes) - Permutazione dei byte (ShiftRows) - Ricombinazione lineare dei byte (MixColumns) - Aggiunta della chiave (XOR byte per byte con i byte della chiave) (AddRoundKey)

La logica di funzionamento è la seguente: preso lo stato, composto da 128 bit, 16 byte, rappresentato da una matrice 4x4

Ogni colonna è una parola a 32 bit, e lo stato è visto come la composizione di 4 colonne. La chiave, in questo caso di 128 bit, anch’essa rappresentata da 4 colonne da 32 bit

viene mandata in ingresso ad un keyschedule, un algoritmo che parallelamente all’esecuzione dei round, produce, a partire dai 128 bit di chiave, le 44 sottochiavi utilizzate nei vari round.

Page 19: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 19

Lo schema di funzionamento è il seguente: entrano i 16 byte di testo in chiaro, la prima cosa che si fa, si aggiunge la chiave (XOR byte a byte, consumo le prime 4 colonne delle 44), successivamente eseguo la sequenza dei 10 round tutti uguali tranne l’ultimo, per ognuno dei quali eseguo le 4 operazioni sopraelencate, tranne nell’ultimo in cui non viene eseguita la MixColumns. Dopodiché la decifratura avviene nel seguente modo: lo schema di decifratura è lo stesso, solo che in ogni scatoletta compare la funzione inversa alla precedente (l’inversa della xor è la xor) quello che succede in AES è che dal punto di vista realizzativo, gli algoritmi che realizzano le funzioni inverse non sono gli stessi delle funzioni originarie come accadeva nel DES in cui bastava invertire l’inserimento delle

subkeys ma l’algoritmo era lo stesso. Analizziamo la struttura di un singolo round. È facile notare che l’unità base di AES è il byte, a differenza del DES in cui venivano effettuate operazioni anche sui singoli bit.

Questo perché AES è software oriented e a livello sw il byte è gestibile in maniera più comoda del bit. Un’altra cosa che si nota è la parallelizzazione delle operazioni che velocizzano il processo. In figura viene mostrato il modo in cui agiscono le singole operazioni sopra descritte: Sostituzione dei byte, permutazione, ricombinazione lineare, somma modulo due dei byte della sub key. Come avviene la byte substitution SubByte: si basa su un’unica S-box di 256 elementi (16x16) che contiene la permutazione dei 256 possibili valori assunti da un byte, cioè dei numeri interi tra 0 e 255 rappresentati in esadecimale. La S-box mappa un byte in ingresso in uno d’uscita, i primi 4 bit del byte in ingresso rappresentano la riga, i restanti 4 la colonna, il valore corrispondente

Page 20: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 20

rappresenta il byte di uscita. L’inversa della S-box è ovviamente la seguente: ovviamente conoscendo la funzione iniziale la sua inversa si può ottenere manualmente. Quella iniziale invece è stata ottenuta tramite una costruzione algebrica denominata algebra GF(28). Continuando con la descrizione delle operazione eseguite, lo ShiftRow è implementato semplicemente

così, la prima riga non è shiftata, la seconda è shiftata circolarmente a sinistra di una posizione, la terza di due e l’ultima di tre. La funzione inversa è semplicemente uno shift circolare a destra delle stesse posizioni. Quest’operazione, apparentemente

semplice, unita alla MixColumns rimescola di molto i byte iniziali. La MixColumns si potrebbe definire in modo tabellare, dimenticandosi dell’algebra, in questo modo

In cui la matrice composta da 16 byte [s0,0 … s3.3], che rappresenta lo stato in ingresso, viene moltiplicata a sinistra per un’altra matrice di byte esadecimali, facendo proprio il prodotto matriciale, con l’accortezza che le somme vanno sostituite con la somma modulo 2; la matrice che esce [s’0,0 … s’3.3] è l’uscita della funzione.

La funzione di aggiunta della chiave infine, non ha bisogno di ulteriori commenti, è semplicemente la somma modulo 2 byte a byte con i byte delle subkeys. È interessante invece vedere come avviene il keyscheduling: osservando la figura a lato ad esempio, w4 si ottiene come xor tra w0 e una trasformazione non lineare di w3, le parole sono di 32 bit, ad esempio w0 è tutta la prima colonna. Nella g c’è dentro una funzione che fa permutazione, in particolare fa rotazione, e poi c’è una funzione di sostituzione basata su s-box.

Vediamo ora come è possibile implementare efficientemente AES su un’architettura a 8-bit come quella delle smartcard. Innanzitutto va osservato che le operazioni del singolo round come SubByte, la ShiftRow e la AddRoundKey, sono tutte operazioni che si applicano al singolo byte, quindi sono facilmente adattabili ad un processore ad 8 bit, meno intuitiva è invece la MixColumns, ma viene fatto in questo modo. Definisco una tabella di 256 elementi, costo di memoria 256 byte, che posso calcolare offline, e che chiamo X2[i]=[02]*i con i=[00],…,[FF], prendo poi una variabile temporale Tmp = s0,j + s1,j + s2,j+ s3,j (con + somma modulo 2). I valori del nuovo stato saranno calcolati come segue: in quanto

Page 21: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 21

In questo modo l’algoritmo di Rijndael può essere serializzato riducendo tutto a calcoli fatti su singoli byte, in più il tempo di calcolo di ogni byte del nuovo stato è sempre lo stesso, in quanto non dipende dagli operandi, e quindi questo sconfigge l’attacco di Time Analysis. AES su un’architettura a 32-bit Il tutto funziona meglio se si hanno CPU a 32 bit, che è il valore per cui è stato pensato AES. Il calcolo del round si riduce al calcolo di 4 tabelle di 256 parole, in tutto 4096 byte di memoria, che mi permettono di calcolare la colonna j-ima dello stato di uscita come

dove la tabella Tk(x) con k=0,1,2,3 x è un byte, contiene parole a 32 bit che si ottengono in questo modo: si prende il byte x lo si trasforma con la s-box ottenendo S(x), e poi se ne fa il prodotto con la colonna k-ima della matrice MixColumns data. In questo modo io ho fatto SubByte calcolando S(x), lo ShiftRow lo effettuo prendendo gli indici j-i delle varie si (gli indici j sono calcolati mod4 cioè per j=0, j-1=4), la MixColumns me la sono calcolata nelle 4 tabelle, la AddRoundKey lo faccio sommando modulo 2 kj. Anche in questo caso il calcolo di ogni colonna del nuovo stato è indipendente dal valore della chiave e degli operandi, resta quindi sempre robusto contro un attacco di Time Analysis. Finora abbiamo visto come sia DES che AES usino la struttura round + keyschedule, vediamo ora un cifrario che non usa il keyschedule. Cifrario Blowfish. È un cifrario a blocchi di 64 bit, la chiave può avere un valore variabile da 1 e 14 parole di 32 bit, l’algoritmo si basa su un contenuto di memoria non indifferente, esattamente su un array di 18 parole P1....P18 a 32 bit, e 4 s-box indirizzabili con 8 bit, quindi contengono 256x4 elementi, ognuno dei quali contiene una parola a 32 bit; quest’algoritmo è ottimizzato per architetture a 32 bit. Le parole P e le 4 s-box sono le quantità che devono essere memorizzate per eseguire quest’algoritmo, 1042 parole da 32 bit, quindi vengono richiesti 4168 byte. Anche la codifica di blowfish è organizzata a round, ogni round ha una struttura simile a quella di Feistel ma con lievi modifiche, i blocchi con “ ≈ “ sono blocchi XOR, il blocco del testo in chiaro a 64 bit viene diviso in due da 32 di cui una viene messa in xor con la prima parola P1 e poi mandata in ingresso ad una funzione F non invertibile, l’uscita viene messa in xor con la metà destra, e poi le due metà vengono scambiate. Cosa fa l’algoritmo, a differenza di Feistel, per renderlo più robusto, la metà sinistra Li-1 invece di essere

mandata così com’è a destra, subisce una prima trasformazione con la parola Pi creando Ri; la metà sinistra in uscita Li è data da una trasformazione della metà destra Ri tramite F, messa in xor con la metà destra Ri-1, e ciò si ripete 16 volte. Si noti come quest’algoritmo si basi completamente su due sole operazioni, somma modulo2 e somma modulo32, in quanto pensato per essere particolarmente veloce in esecuzione. La funzione F è fatta in questo modo, prende in ingresso 32 bit, 4 byte, e fa la seguente operazione:

In tutto ciò dove si trova la chiave? La chiave si trova dentro le S e dentro le P. Esse vanno inizializzate con dei bit casuali, in realtà si prendono i primi 4168 byte della parte frazionaria di π (scritto in binario) e si caricano dentro P ed S, i byte di P vengono poi messi in xor con la chiave. Ovviamente se

Page 22: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 22

ho una chiave a 128 bit devo ripeterla più volte per farne l’xor con le 18 parole a 32 bit. Successivamente prendo una parola nulla (tutti zero) da 64 bit e la cifro, la parola in uscita divisa in 32 + 32, la metto in xor con P1 e P2, la stessa parola la ricifro (questa volta con P1 e P2 modificati) e ciò che ottengo lo metto in xor con P3 e P4 e così via finché non aggiorno tutte le P e le S. Facendo un conto, per inizializzare la cifrante, abbiamo bisogno di 521 esecuzioni del codice, 521 cifrature, ciò diviene fastidioso se si cambia spesso la chiave. Il lato positivo però è che se un’attaccante deve provare diverse chiavi,per ogni chiave deve prima inizializzarla e poi provarla, la complessità computazionale di un attacco a forza bruta diventa enormemente elevata.

LEZ. 07 – 10/10 Cifrari a Blocco e a Flusso (parte2, RC4) / Modi operativi

Vediamo ora un esempio di Cifrario a Flusso precisamente il Cifrario RC4, un cifrario molto diffuso e installato nella maggior parte delle piattaforme software (web SSL/TLS, Wi-Fi WEP). È un cifrario a flusso, orientato al byte, la cui logica di funzionamento è ispirata dal OneTimePad, in quanto produce un Keystream in byte (non è orientato al bit) e quindi una sequenza di byte che idealmente si presenta come una sequenza casuale, e in seguito non fa altro che mettere in xor i dati da cifrare con questa sequenza pseudo casuale . Pseudo poiché prodotta con meccanismo deterministico, e che può quindi essere riprodotta in ricezione per recuperare i testi in chiaro, a patto di essere in possesso dell’informazione segreta: la chiave. La logica quindi è questa, imitare il OTP ma non con dei dati veramente random, altrimenti me ne servirebbero tanti quanti sono i byte del testo in chiaro che voglio mandare, ma dei dati pseudo random, generati cioè da una macchinetta che va inizializzata usando la chiave. Inizializzazione. Tutta l’implementazione si basa su di un vettore di 256 byte chiamato S[i] il quale rappresenta lo stato del cifrario. In ogni dato istante in cui il cifrario agisce, questo vettore contiene

una permutazione dei numeri interi compresi tra 0 e 255. Per inizializzare questa permutazione si scandisce questo vettore e alla componente i-ma si da il valor i, quindi da 0 a 255, e poi nel vettore temporaneo T[i] anch’esso di 256 elementi che funge da variabile d’appoggio, si carica dentro il byte di chiave. Keylen è una variabile intera che esprime il numero di byte di cui si compone la chiave, dall’algoritmo si evince che questa cosa ha senso per chiavi di lunghezza compresa tra 1 e 256 byte. In pratica si prendono i byte di chiave e si scrivono in T[i] eventualmente ripetendoli se la chiave è più corta di T[i]. Dopodiché cosa si fa, si introduce un indice j che mi permette di introdurre la chiave in S[i],

permutando infine le sue componenti con un operazione di swap, da notare che il particolare tipo di permutazione dipende dalla chiave, poiché è presente T[i].

Cifratura. La cifratura è elementare, è fatta come il OTP, un byte di testo cifrato si ottiene dal corrispondente byte i testo in chiaro, facendo l’xor di questo byte con S[t], cioè con una componente, la t-ima del vettore S. Decifratura. Per recuperare il testo in chiaro, facendo semplicemente l’xor del testo cifrato con la stessa componente. S[t] come si trova, è la componente del vettore S[i] allo stato t. È importante fare lo swap(S[i], S[j]) perché altrimenti potrei ottenere due valori uguali di t, e se dovessi mandare di nuovo lo stesso byte, introdurrei una regolarità nella cifratura. Riguardo la sicurezza di questo cifrario, sono noti problemi riguardanti i primi byte cifrati, i quali possono subire attacchi di natura statistica, ma in effetti non è stato pubblicato nessun attacco realmente vincente, stando attenti ovviamente ad evitare i primi byte di keystream. La cosa importante è non riusare mai la stessa chiave in presenza per esempio di una ritrasmissione.

Page 23: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 23

Ritornando ora ai cifrari a blocco, mi chiedo: come faccio a cifrare un testo di lunghezza qualsiasi, che non sia proprio lungo quanto un blocco? Con i cosiddetti modi operativi. Modi Operativi. Nascono dal fatto che il plaintext può avere lunghezza qualsiasi, potrebbe anche essere più corto del blocco. La soluzione più banale consiste nel prendere i dati e segmentarli con una lunghezza pari alla lunghezza del blocco, eventualmente aggiungendo qualcosa per far si che il testo passato in ingresso alla cifrante, abbia lunghezza che è multiplo intero della lunghezza del blocco. La porzione di bit non significativi aggiunti per il motivo sopra detto, si chiama Padding. Quindi la soluzione banale è, faccio Padding e poi segmento a blocchi, il modo in cui andrò poi a cifrare questi blocchi è definito dai Modi Operativi. Vi sono due tipi di Modi Operativi, Modi operativi a Blocco, Modi operativi a Flusso (attenzione: entrambi vengono usati per le cifranti a Blocco, le cifranti a Flusso non utilizzano Modi Operativi). Il Modo operativo a Blocco definisce una regola che permette di fare Padding e poi concatenazione della cifratura dei diversi blocchi così creati. Esso utilizza come funzione, che richiama per ogni blocco, la cifrante a Blocco. Il Modo operativo a Flusso è un algoritmo che, basandosi sulla cifrante a Blocco, produce un keystream, e dopodiché usa il keystream per cifrare i dati. Padding e Modi Operativi a Blocco. Non ci sono regole generali per effettuare il Padding, l’importante è che si rispettino due criteri: che sia univocamente rimovibile in ricezione senza ambiguità, che non si lascino bit non definiti, perché andranno a costituire vulnerabilità. Un esempio di regola di Padding è la seguente: dato l lunghezza del messaggio, b è la dimensione del blocco base, se l mod b≠0 (vuol dire che l non è multiplo di b) aggiungi il numero di byte nulli che serve a rendere l multiplo intero di b cioè , altrimenti non aggiungere nulla. Questo Padding

funziona? No, perché non è univoco il Padding che ho aggiunto, non riesco a distinguere un messaggio che finisce con un byte nullo di per se, con un messaggio in cui io per Padding ho aggiunto un byte nullo. Questo ad esempio spiega perché il numero di byte di Padding che devo aggiungere è compreso tra 1 e b, non 0 e b-1, perché uno almeno bisogna metterlo per forza, se è già multiplo di 16 byte ad esempio, è una sfiga, perché bisogna aggiungerne altri 16 per rendere univocamente rimovibile il Padding. Una regola per esempio potrebbe essere questa: prendi il pacchetto, aggiungi un byte fatto così 1000000, un 1 e tutti 0, se il pacchetto così ottenuto (pacchetto originale più byte come prima) è multiplo intero di b ok, altrimenti aggiungi tanti byte nulli quanti ne servono per rendere il tutto multiplo intero di b. La regola, semplice, di rimozione di questo Padding in ricezione consiste nel rimuovere, dal fondo, tutti gli zeri, quando trovi un 1 rimuovi anche quello e ciò che ottieni è il pacchetto originale. Chiarito il funzionamento del Padding, possiamo assumere nella cifratura a Blocchi che il nostro messaggio sarà composto da K blocchi di plaintext Pi, i=1…k, tutti di lunghezza uguale al singolo blocco. Electronic Code Book (ECB). La cifratura più brutale mi dice che io ho una macchinetta che dato un blocco, me lo sa cifrare data una certa chiave, se ho K blocchi la applico K volte: questo si chiama Electronic Code Book. Questo modo operativo non è buono poiché facilmente può lasciar trasparire qualcosa dei dati, in particolare se due blocchi del testo in chiaro si ripetono, i corrispondenti blocchi del ciphertext saranno identici. Un’immediata evoluzione di questo è allora il Cipher Block Chaining (CBC).

Page 24: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 24

È sempre un modo operativo a blocco che necessita quindi di Padding, ma ha una struttura differente, concatenata. Ogni singolo blocco è pari all’ECB, ma prima di cifrare un blocco, lo si mette in xor con il blocco ciphertxt precedente. In ricezione decifro il blocco Ci e poi lo metto in xor con il blocco Ci-1. Sia in cifratura che in decifratura ho bisogno quindi di questo blocco Ci-1 che chiameremo Initial Vector (IV). Questo modo operativo risolve il problema dell’ECB in quanto se due blocchi in ingresso dovessero essere uguali, le corrispondenti uscite non sono uguali perché

gli ingressi della macchina cifrante, a parità di plaintext, non sono gli stessi. A differenza dell’ECB ovviamente il CBC è soggetto all’Error Propagation, cosa facilmente intuibile. Initial Vector (IV). Se scelgo un IV fisso, avrei lo stesso IV e la stessa chiave per due messaggi differenti, che però con buona probabilità possono iniziare allo stesso modo per via delle intestazioni. Avrei quindi i due primi blocchi del testo cifrato dei due messaggi, uguali, e questo mi porterebbe ad una perdita di informazione -> Information Leakage. Sappiamo inoltre che nel Keystream se io uso la stessa chiave per messaggi diversi produco lo stesso Keystream e questo non va bene. In questo caso ciò che produce lo stesso testo cifrato, a parità di testo in chiaro, non è solo la chiave, ma la coppia (IV,chiave), quindi quello che è importante è non ripetere mai la coppia (IV,chiave), uno dei due deve essere cambiato. Provando a cambiare IV, potrei prendere un contatore, IV=0 per il primo messaggio, IV=1 per il secondo, e così via, questa cosa però non va bene perché se i messaggi dovessero cambiare di poco, cambiando di poco anche l’IV avrei una correlazione evidente. Potrei crearlo randomico, ma a fronte di k blocchi da cifrare, io ne devo mandare k+1 poiché devo aggiungere C0 che è l’IV, che il destinatario non lo conosce in quanto random. Ho creato overhead, che è tanto più grande quanto più è piccolo k, in più ho bisogno di una sorgente di numeri casuali affidabile crittograficamente, non sempre disponibile. La soluzione risiede nell’uso dei cosiddetti Nonce (Number used ONCE), cioè un numero che viene usato una sola volta, nel contesto di interesse del protocollo crittografico che lo usa. Per esempio un numero casuale a 128 bit si può ritenere lecitamente che sia un Nonce, se la sorgente casuale che lo genera è veramente casuale. Può andar bene anche un contatore ciclico a 128 bit, purché si debbano contare una quantità di cose inferiore a 2128. Per usare il Nonce su un blocco di 128 bit allora, posso definire sufficientemente un contatore ciclico a 64 bit, dopodiché uso la mia cifrante con la chiave nota e cifro il Nonce, ovviamente dopo aver fatto Padding (poiché il blocco è 128 bit mentre il Nonce è 64 bit), questo blocco di dati cifrati lo uso come IV, e poi cifro il mio messaggio in modalità CBC. Al destinatario dovrò dare il Nonce e C1….k ma non C0 che potrà ricavarsi avendo il Nonce e la chiave della cifrante. In questo modo per cifrare diversi messaggi, lascio fissa la chiave che è oneroso cambiare, ma cambio l’IV C0, cosa che ottengo cambiando il Nonce. Modi Operativi a Flusso. Il punto di partenza è sempre la cifrante a Blocco, altrimenti non avrei bisogno di modi operativi, che però questa volta userò per produrre keystream che puoi userò per cifrare i dati. Output FeedBack (OFB). Un possibile modo operativo a flusso è l’Output FeedBack (OFB) che fa la seguente cosa: parte da un vettore iniziale IV su cui valgono tutte le considerazioni fatte prima, e poi applica iterativamente

queste equazioni, dove K è la chiave, quindi genera una sequenza di blocchi, e questo può essere fatto anche offline, prima della cifratura. Successivamente mette in xor il keystream ottenuto con i byte del testo in chiaro, quindi

Page 25: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 25

fornirò al destinatario i Ci…k più l’IV o qualche altra informazione tramite la quale ricavare l’IV. Questo è un cifrante a flusso di tipo Sincrono, quindi se perdo il passo in ricezione non capisco più niente. Ma se la cifrante è buona in questo modo abbiamo quella che possiamo ritenere un’approssimazione pratica ma efficace del OTP. Cipher FeedBack (CFB). È un modo operativo a flusso auto sincronizzante, che non richiede cioè sincronizzazione, e la cui equazione base funziona in questo modo, si prende il blocco i-mo e lo si mette in xor con dei byte di keystream ottenuti cifrando, con la chiave segreta K, il precedente blocco di ciphertext. Ovviamente come tutti i modi operativi si parte da un vettore iniziale con tutte le considerazioni fatte prima. Counter Mode (CTR). Un modo operativo interessante che è a flusso ma non richiede inizializzazione è il cosiddetto Counter Mode. Secondo questo modo operativo si produce il keystream, poi una volta prodotto il keystream, il testo cifrato si produce così Anche in questo caso sono stati indicati con k i blocchi di testo in chiaro, ma non c’è nessun motivo di fare Padding del testo in chiaro, perché questo è un modo operativo a flusso, quindi come tale prendo il messaggio, lo metto in xor con i byte del keystream necessari, quelli che ho prodotto in più li butto via. Il keystream in questo caso viene prodotto facendo cifratura, con la chiave segreta assegnata, di una quantità che è la concatenazione ( || ) di un Nonce e di un contatore i. Supponiamo per la cifrante AES a 128 bit (posso formare i 128 bit con un contatore a 64 bit), un Nonce a 48 bit più altri 16 bit tutti nulli o per altri scopi. Il blocco i-mo si ottiene incrementando i, poi in tutti i blocchi di uno stesso messaggio c’è sempre lo stesso Nonce. In ricezione per permettere la ricostruzione è sufficiente comunicare il Nonce, poiché la chiave è nota. Il vantaggio è che questo consente eventualmente un’esecuzione in parallelo cosa non permessa dal CBC in cui la decifratura è solo sequenziale, inoltre permette quello che si chiama Random Access del testo, se voglio decifrare solo il 16° blocco di testo in chiaro, posso farlo senza decifrare i precedenti, cosa non fattibile negli altri modi operativi. La cosa importante è che non si ripeta la stringa concatenata, quindi se n sono i bit del contatore, deve essere 2n>k. Problemi dei modi operativi. Il modo operativo è un qualcosa che usa quel blocchetto che è la cifrante, quindi la sua sicurezza è strettamente legata alla sicurezza della cifrante, di per sé non aumenterà la sicurezza, ma può solo diminuirla. In più anche se la cifrante di per sé è robusta, modi operativi diversi possono introdurre vulnerabilità. Ciò che và sottolineato è che a prescindere dalla cifrante a blocco o a flusso che si sta usando, a prescindere dal modo operativo implementato, comunque la cifratura serve a fornire un servizio di confidenzialità, cioè celare il contenuto dei dati a terze parti non autorizzate; non serve in nessun modo ad impedire che l’attaccante manipoli i dati. Cifrare non vuol dire impedire la manipolazione dei dati.

LEZ. 08 – 11/10 Hash

Hash Crittografico. È una di quelle funzioni largamente utilizzate in crittografia, in particolare vengono utilizzate in due moduli, quelli che producono MAC (Message Authentication Code) e quelli che producono Firme, ma non soltanto per questi. L’idea di base dell’Hash è quella di realizzare una sorta di “impronta” di un

Page 26: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 26

messaggio, in questo caso di un blocco di dati di lunghezza arbitraria. Si usa il termine impronta in quanto come vedremo, messaggi diversi possono avere lo stesso hash, quindi non c’è corrispondenza biunivoca. L’hash si può fare anche dipendente da un parametro che poi dopo assume il significato di chiave, se si usano hash privi di chiave, bisogna prevedere che dopo l’hash venga memorizzato in modo sicuro. Se per esempio ritengo insicuro il disco del PC, ma ritengo sicura la memoria USB che mi porto sempre dietro, posso memorizzare l’hash di tutti i file critici che ho sul PC nella memoria USB, dopodiché ogni giorno prima di aprire il file sul PC ci si ricalcola l’hash di quel file e lo si confronta con quello in memoria USB, se sono diversi reputo che il file sia stato modificato. L’attacco classico è quello di modificare il file in maniera tale che l’hash poi risulta lo stesso, e lo scopo dell’hash Crittografico è proprio quello di evitare che ciò avvenga. La funzione Hash dipende da un quadrupla (X,Y,K,H) di insiemi: - X: insieme di possibili messaggi di ingresso (potenzialmente infinito). - Y: insieme finito dei possibili valori di Hash (gli hash sono lunghi normalmente tra 128 e

512 bit). - K: insieme delle chiavi, eventualmente ridotto ad un solo elemento se la funzione hash è

senza chiave. Dopodiché per ogni k Є K esiste un hk Є H t.c. hk: X�Y è un mapping da X a Y, cioè una funzione definita in X che produce per ogni messaggio di X un valore in Y, funzione che però non è biunivoca. Dal punto di vista crittografico, ciò che interessa è costruire funzioni hash che rendano infattibili computazionalmente i seguenti problemi:

premessa: Dare y vuol dire dare un sottoinsieme di x poiché più messaggi possono avere lo stesso hash, quindi l’insieme X è partizionato in tanti sottoinsiemi, ognuno corrispondente a diversi valori di y, questo perché la funzione hash non è biunivoca, quindi a valori diversi di y corrispondono sottoinsiemi disgiunti in X.

- Preimage (Pmg): data una funzione hash hk e dato un valore y, trovare un x t.c. hk(x)=y. - Second Preimage (SPmg): dato un y (quindi un sottoinsieme di X), una funzione hash hk e

un valore x, trovare un altro x’≠x appartenente allo stesso sottoinsieme, t.c. hk(x’)= hk(x). - Collision(Cls): data una funzione hash hk, trovare due elementi distinti x’, x t.c. hk(x’)= hk(x).

La funzione dell’Hash Crittografico è quella di rendere la soluzione di questi problemi, computazionalmente impossibile. Per fare questo si introduce un modello di funzione Hash ideale: The Random Oracle Model. La definizione intuitiva di questo modello è che in sostanza l’unico modo per calcolarsi h(x) è valutarla x per x, cioè indipendentemente da quante volte l’ho già valutata, non c’è nessun modo per calcolarsi h(x) se non nel punto x. Supponiamo che l’hash si calcoli in questo modo: h(x) = a·x mod m, cioè traducendo il messaggio x in un numero intero, avendo fissati a e m. conoscendo l’hash su x io posso calcolare l’hash di b·x in questo modo: h(b·x) = a·b·x mod m = b·h(x) mod m, cioè posso calcolare l’hash (h(b·x)) senza conoscere la sua espressione diretta, ma semplicemente con delle operazioni che coinvolgono altri valori di hash (h(x)), e questo non corrisponde al modello di una funzione di hash ideale. Data la definizione intuitiva, formalmente si dice che l’unico modo per conoscere l’hash di x è interrogare l’oracolo, il quale fa la seguente cosa: nell’insieme di tutte le funzioni hash possibili che mappano x in y, ne sceglie una a caso, poi prende x calcola h(x) e restituisce y. Come se esistesse una enorme tabella che a fronte di un valore di x restituisce un y, e la tabella è stata compilata a caso, quindi non c’è nessuna regola matematica per calcolare h(x) se non interrogando la tabella. La proprietà fondamentale che caratterizza un oracolo random è questa:

Page 27: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 27

cioè, supponiamo di conoscere gli h(x) per tutti gli x appartenenti ad un certo sottoinsieme, la probabilità che, per un determinato valore di x non appartenente ad X0, , è pari ad 1/M, dove

M è la cardinalità dell’insieme Y. Cioè per quanti valori io conosca e abbia già appreso su h(x), il prossimo valore è un valore random, e quindi ogni valore y è equiprobabile. Il valore di M sarà pari a 2n se n è la lunghezza in bit dell’hash, e poiché l’hash è in genere lungo dai 128 ai 512 bit, questa probabilità sarà molto piccola. Bisogna capire perché l’hash è così grande. Poiché l’hash è il mattone base per poter realizzare ad esempio le firme, vuol dire che se l’hash è lungo 512 bit, come minimo la firma sarà lunga 512 bit se non di più, e siccome a volte è necessario firmare documenti lunghi poche decine di byte, avere una firma di 512 bit non è comodo. Algoritmi Randomizzati (per la soluzione dei problemi relativi agli hash). In genere un algoritmo è una sequenza di passi che si esegue per portare a termine un calcolo; gli algoritmi randomizzati, sono algoritmi nel corso dei quali alcune variabili utilizzano valori casuali per fare delle scelte nell’algoritmo. Algoritmo di Las Vegas: può fallire nel dare una risposta (non sa rispondere) ma se risponde, sicuramente è la risposta giusta. È randomizzato nel senso che c’è una certa probabilità che fallisca, che non sa rispondere, ma se risponde, la risposta è quella giusta. Si può parlare allora di Probabilità di successo nel caso peggiore Worst case e media Average. Worste-case success Probability ε: per qualsiasi istanza del problema, cioè comunque scegliamo i dati di input e i parametri, la probabilità di successo è almeno ε. Average-case success Probability ε: mediando su tutte le possibili istanze del problema, la probabilità di successo è maggiore o uguale a ε. Nel nostro caso un algoritmo di Las Vegas (ε,q) avrà una probabilità nel caso peggiore o media ε, con una complessità (numero di interrogazioni dell’oracolo) pari a q. Gli algoritmi che vedremo sono l’equivalente dell’attacco a forza bruta, e nel caso di Hash ideale rappresentano l’unico modo per risolvere i tre problemi di cui abbiamo parlato prima. Oracle model agorithm for Pmg: FINDPREIMAGE(h,y,q).

Per un hash ideale, la soluzione del problema Preimage è la seguente: si sceglie a caso un sottoinsieme X0 di X composto da q elementi; q è la complessità che mi sto dando, cioè il numero delle volte che devo calcolare l’hash. Dopodiché per ogni valore di x calcolo h(x) se l’ho

trovata bene, ho trovato la contro immagine, restituisci x altrimenti fallimento. La probabilità di successo media è:

dove è la probabilità di fallire su tutte le istanze del problema. Per essere un buon

algoritmo deve essere , per fare ciò devo agire sull’M, devo fare l’hash abbastanza lungo da

rendere M grande, di modo che per rendere la quantità l’attaccante dovrebbe fare un numero di

valutazione della funzione hash infattibile.

Oracle model agorithm for SPmg: FINDSECONDPREIMAGE(h,x,q). Dato x e h, mi calcolo y, prendo il sottoinsieme X0 di q-1 elementi e li provo tutti per vedere se ce ne è uno che da lo stesso valore di y cioè una SecondPreimage

La probabilità di successo media è:

Oracle model agorithm for Cls: FINDSECOLLISION(h,q).

Page 28: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 28

Data la funzione h e la complessità q, scelgo a caso un sottoinsieme di dimensione q, calcolo l’hash per tutti i valori di e vado a cercare se trovo per caso due valori x e x’

tali per cui yx=yx’ e se questo esiste per qualche x≠x’. Se questo è vero restituisce la coppia x e x’ che mi creano collisione, cioè messaggi distinti che hanno lo stesso hash.

La probabilità di successo media è: ε= 1–(1–1/M)·(1–2/M)·…·[1–(q–1)/M]. Il valore di q che rende ε>1/2 (successo dell’attaccante) è q=1.17 M1/2. Se io prendo un hash lungo 64 bit, M=264, q=232 che è un numero di valutazioni fattibilissimo. Una funzione hash è una funzione che prende qualunque testo in ingresso di lunghezza qualsiasi e lo vuol mappare su un insieme a M bit, l’hash. Ci sono poi le funzioni di Compressione, che prendono stringhe di (m+t) bit e le mappano su stringhe di m bit. È possibile allora realizzare una funzione hash sicura, partendo da una funzione di Compressione? Un po’ come per i cifrari in cui si prende un algoritmo più o meno semplice (round) e poi lo si ripete più volte, allo stesso modo per una funzione hash si può prendere una funzione un po’ più semplice come la funzione di compressione, e iterarla più volte. In generale allora un hash può essere pensato come una fase di Preprocessing una fase di Iterative Processing calcolo iterativo, e poi un Output Transformation finale. Ci sono due studiosi, Merkle-Damgard, che hanno dimostrato che costruire un hash con la struttura iterativa che vedremo adesso, non è limitante, cioè è possibile costruire hash iterativi resistenti alla collisione, quindi sicuri. Com’è fatto allora in generale un hash iterativo, prendo un messaggio x di lunghezza qualsiasi, che sia |x|≥m+t+1, se fosse lungo quanto m+t basterebbe la funzione di compressione. Per prima cosa vi applico il Padding, o comunque lo estendo in maniera tale che la sua lunghezza sia un multiplo intero di t bit, ottenendo così la stringa Y che poi partiziono in L blocchetti Y = Y0 || Y2 || … || YL-1, ognuno di dimensione t bit, ovviamente dovrà essere L×t≥lenght(x). Questo è il passo di Preprocessing. Successivamente il cuore dell’algoritmo consiste nel prendere la funzione di compressione la quale prende in ingresso m+t bit e ne restituisce m bit; gli m+t bit che prende in ingresso sono costituiti da una variabile di stato CVi-1 concatenati al blocchetto i-mo di t bit che ho creato prima. In seguito questi m bit in uscita dalla funzione di compressione, rappresentano la variabile di stato del prossimo calcolo, questo per 1<i<L. Anche in questo caso, come nel CBC, ho bisogno di un IV Initialization Vector CV0 che va dato. Alla fine quando ho esaurito tutti i blocchetti del messaggio, otterrò uno CVL che trasformo per ottenere il valore dell’hash finale.

Quello che ci chiediamo ora è se questa struttura introduca o no delle vulnerabilità, la risposta è si e no. No, nel senso che Merkle-Damgard hanno dimostrato che è possibile avere una struttura iterativa probabilmente sicura, nel senso che un hash ottenuto in questo modo è resistente alla collisione se lo è la funzione di compressione. Quindi il problema è ridotto a trovare una funzione di compressione che sia resistente alla collisione, che in ultima analisi abbiamo visto significa scegliere m abbastanza grande. La risposta è anche si, poiché vi sono degli attacchi che dipendono da questa struttura iterativa, a seconda poi del modo particolare in cui la funzione hash è usata per calcolare gli autenticatori (MAC).

Page 29: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 29

Provably Secure Hash Functions. Le funzioni hash in pratica sono definite da standard, i più utilizzati sono MD5 (Message Digest (riassumere)) che produce un hash a 128 bit, e SHA-1 (Secure Hash Algorithm) con le varianti più recenti SHA-256, 348, 512 riferite alla lunghezza degli hash in uscita. La complessità, ammesso che SHA non permetta attacchi se non quello a forza bruta, cosa per altro vera per ora, è pari a 2#bit/2 ad esempio per SHA-1 che produce 160 bit la complessità è pari a 280. SHA-1: nato per estendere la sicurezza di MD5, si applica a stringhe binarie di lunghezza inferiore a 264 bit, il suo blocco di uscita è 160 bit, è realizzato in questo modo e si basa su una funzione di compressione con un blocco interno di 512 bit. Il messaggio x si estende aggiungendovi un bit uguale ad 1, un certo numero di d bit nulli, e poi 64 bit che contengono dentro la rappresentazione binaria della lunghezza in bit di x, siccome x può essere lungo 264, servono 64 bit per dire quant’è lungo x. (447=512-w-1). L’algoritmo utilizzato da SHA è il seguente:

Si prende il testo e lo si divide in blocchi M1 || M2 || … || Mn, lunghi 512 bit cioè 16 parole W0…15 da 32 bit, e per i=1:n si esegue l’algoritmo utilizzando la variabile di stato H0, H1, H2, H3, H4, che sono 5 parole da 32 bit (quindi 160 bit) esadecimali, che vengono inizializzate come mostrato su. Quello che si tenta di fare è un gran mescolamento unito ad una serie di operazioni elementari come xor e shift a sinistra.

LEZ. 09 – 12/10 MAC

MAC (Message Authentication Code). Abbiamo visto come gli Hash vengono utilizzate in molte applicazioni crittografiche, una di queste è sicuramente il MAC (Message Authentication Code), un meccanismo che fornisce autenticazione del massaggio, ma serve anche a validare l’integrità del messaggio, validare l’identità di chi ha originato il messaggio, ed infine garantisce il servizio di Non Repudation. I primi due di questi servizi possono essere realizzati con una crittografia basata su chiavi condivise simmetriche, quando si parla di MAC realizzato con crittografia basata su chiave pubblica, si parla generalmente di Firme (Signature), il meccanismo però è lo stesso, è sempre il MAC che supporta questi 3 tipi di servizio. Il contesto in cui si realizza il MAC è costituito da due entità che comunicano A e B, A vuole mandare un messaggio a B e B vuole verificare che colui che ha originato il messaggio sia proprio A e che il messaggio non sia stato alterato. Si parte allora dal messaggio che si vuole trasmettere, e dalla chiave che è condivisa col destinatario del messaggio, quindi al messaggio pronto per essere trasmesso sul canale insicuro, viene appeso il MAC, una stringa binaria calcolata come funzione di due input, il messaggio stesso e la chiave segreta. Il MAC quindi è una funzione a due ingressi, chiave segreta e messaggio più eventuali altri parametri specifici di uno schema di MAC; da qui si calcola la stringa

Page 30: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 30

binaria da appendere al messaggio e poi si invia messaggio più il MAC. Il ricevitore fa esattamente ciò che si fa per la rivelazione d’errore, prende il solo messaggio e ricalcola a sua volta l’autenticatore relativo al messaggio ricevuto, ciò può farlo in quanto conosce la chiave segreta e l’algoritmo di generazione Ck (Checksum) del MAC. Poi prende i due MAC, ricevuto e calcolato, e li confronta, se sono uguali conclude che il messaggio non è stato modificato e inoltre il messaggio proviene dall’unica altra entità che oltre a lui conosce la chiave k. Definiamo ora quali tipi di attacchi possono essere rivolti contro il MAC. Il tipico attacco fattibile è la Forgiatura: MAC Forge, fabbricazione di un MAC falso cioè, l’attaccante riesce a creare una coppia (mi,Ci) messaggio - checksum (che è l’autenticatore del messaggio), valida, cioè C è proprio l’autenticatore di quel messaggio m, ma questo messaggio non è stato mai visto da Alice. Si hanno diverse possibilità di attacco che corrispondono anche a diversi gradi di robustezza nello schema di MAC: l’attaccante non sa nulla, l’attaccante conosce un certo numero q di coppie valide osservate sul canale, ultimo e più forte, l’attaccante può scegliere e ottenere da Alice q coppie valide. Il prodotto dell’attacco è la fabbricazione, le coppie valida, si distinguono in Esistenziali e Selettive. Le prime indicano che questa cosa è fattibile per almeno un messaggio, ma non ho nessun controllo sul messaggio che ne esce fuori, quindi è un attacco più debole; per le seconde invece io scelgo un messaggio che per me ha interesse, e riesco ad ottenerne l’autenticatore da Alice. Come si fa allora ad ottenere questo Checksum crittografico che è il MAC. Gli obbiettivi sono ottenere una specie di impronta, contenente anche una chiave segreta, di un messaggio, che permetta di riconoscere se quest’ultimo è stato alterato, e d’altra parte far si che questo campo che appendo al messaggio abbia un overhead contenuto. Per far ciò ho bisogno di una funzione Hash che prenda in input un qualche cosa che dipende da messaggio e chiave, ricordando poi che le funzioni Hash sono tutte realizzate iterativamente attraverso una funzione di compressione. Ricordando che la robustezza di un hash dipende dalla robustezza della sua funzione di compressione, la realizzazione di un hash con chiave, cioè di un MAC che sia poi robusto, dipende tutto da come noi combiniamo tutto. Se lo facciamo male sono possibili degli attacchi, attacchi che si chiamano Length Extension e Partial Collision. Length Extension Attack: supponiamo che il nostro checksum sia fatto così, C=h(K||m) una certa funzione hash della concatenazione della chiave segreta e del messaggio, ora se la funzione hash fosse l’oracolo random non ci sarebbe nessun problema, siccome però le funzioni hash sono iterative, sfruttando questa iteratività riesco ad ottenere una coppia valida, per di più con una forgiatura selettiva. Dato il messaggio m=m1||m2||…||mk fatto da k blocchi, il suo autenticatore abbiamo detto che è C=h(K||m), se adesso prendo il messaggio m’ composto da m più un blocco: m’=m||mk+1, so calcolare il suo autenticatore? C’ sarebbe dato da C’ = h(K || m’) = f(h(K ||m),mk+1) = f(C,mk+1) questo poiché l’hash è calcolato iterativamente e f è proprio la funzione di compressione. Estendendo il messaggio (length extension) sono riuscito a calcolare l’autenticatore di m’ partendo da quello osservato sul canale e senza aver bisogno della chiave. La falla sta nel fatto che la chiave entra solo nella prima iterazione, allora si potrebbe pensare di inserirla ad ogni iterazione oppure all’ultima, ma ciò da spazio ad un altro tipo di attacco, il Partial Collision Attack. Partial Collision Attack: è un attacco che può essere reso infattibile ma è comunque grave. Supponiamo di avere due messaggi diversi che generano una collisione sulla funzione hash, cioè l’hash di questi due messaggi è lo stesso, calcolato come C=h(m||K), con la chiave alla fine. Se la chiave fosse all’inizio, non potrei rilevare la collisione. Se a partire da questi due messaggi m,m’ che generano una collisione, io creo i relativi messaggi estesi me,me’ definiti come me=m+u, me’=m’+u, gli estendo cioè con lo stesso testo. Succede che i due messaggi sono diversi, perché per ipotesi m,m’ sono diversi, però hanno lo stesso hash, in quanto m,m’ ce l’hanno perché collidono, e siccome la funzione hash è iterativa, anche i due hash dei messaggi estesi daranno luogo ad un collisione. Allora se conoscono l’autenticatore di

Page 31: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 31

uno, posso sapere l’autenticatore di un altro messaggio diverso, quindi mi faccio autenticare un messaggio ma in realtà c’ho l’autenticazione di un altro messaggio senza conoscere la chiave. Ovviamente la premessa è che sono stato capace di trovare una collisione. Una soluzione possibile che è stata trovata è per esempio applicare l’hash due volte h(h(m)||m), calcolo l’hash di m, lo premetto ad m e poi ricalcolo l’hash. Questo tipo di approccio è quello usato da uno dei MAC più diffusi, HMAC. HMAC: l’HMAC di una chiave k si ottiene in questo modo: al posto di hash si può usare una qualunque delle funzioni hash note (MD5, SHA-1), K+ è la chiave con l’aggiunta a sinistra di tanti zeri (zero left padding) quanti servono a raggiungere la dimensione del blocco della funzione hash. Opad e ipad sono le costanti opad=5C5C…5C e ipad=3636…36 in

esadecimale. Partendo da destra, premetto al messaggio l’xor tra la chiave estesa e l’ipad, e ne calcolo l’hash, ma questo non basta perché permette il length extension poiché la chiave compare solo all’inizio, dopo aver prodotto l’hash che dipende dalla chiave, prendo questa stringa, vi premetto di nuovo la chiave (xor tra chiave estesa e opad) e ricalcolo l’hash. In questo modo ho usato due volte l’hash e la chiave non compare solo all’inizio. Il seguente schema mostra come si procede al calcolo:

CBC – MAC. È un MAC basato su funzioni di cifratura, non su hash. Innanzitutto si basa sull’utilizzo di una cifrante a blocco, una qualsiasi, quindi una cifrante che mappa stringhe binarie di n bit (il testo in chiaro), in stringhe binarie di n bit (il testo cifrato). In realtà non ci interessa la cifratura, ma soltanto il random mapping parametrizzato ad una chiave, realizzato dalla cifrante. Allora cosa si fa, si prende il messaggio x, ci si applica eventualmente padding, e si partiziona in blocchi di t bit x1||x2||…||xn dove t è la lunghezza del blocco della cifrante. Partendo poi da uno stato iniziale y0 = IV = 0t calcolo yi = eK(yi–1 + xi), dove eK è la cifrante, e all’n-imo ciclo iterativo ottengo il valore yn che sarà il MAC del

messaggio x, con la chiave k. In questo modo si rispetta il principio secondo cui il MAC sia funzione del messaggio e della chiave, e in più la chiave compare in ogni singolo blocco poiché utilizzata dalla cifrante, quindi ho sempre una struttura iterativa. Il MAC deve dipendere da ogni bit del messaggio, quindi ci aspettiamo che cambiando un solo bit di x devono cambiare almeno la metà dei bit del MAC. Su questo CBC-MAC in realtà non è noto nessun attacco che non sia a forza bruta, che in realtà è come quello di collisione. Consideriamo un certo numero q di messaggi distinti x1,…, xq, ognuno fatto da n blocchi di cui però quelli dal 3° all’n-imo sono uguali in tutti i messaggi, l’attaccante conosce sia i messaggi sia il loro hash (checksum), quindi conosce q coppie messaggio-hash valide, che analizzerà per scoprire se è presente una collisione. La complessità è strettamente legata alla quantità q delle coppie da conoscere, se questo q è abbastanza alto di fatto l’attacco non è fattibile. Dopodiché se trovo una coppia xi, xj che hanno lo stesso MAC, poiché il MAC è calcolato in quel modo e i due messaggi

Page 32: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 32

hanno lo stesso valore del residuo finale, è possibile affermare che due messaggi distinti ma costruiti con la suddetta struttura, che vanno in collisione, avranno uguali i secondi blocchi cifrati, cioè y2(i)=y2(j). Risulteranno uguali allora (y1(i) + x2(i)) = (y1(j) + x2(j)), cioè anche gli argomenti di ek devono essere uguali poiché la funzione di cifrature deve essere biunivoca. Assodato questo io costruisco due nuovi messaggi in questo modo:

u lo faccio autenticare da Alice, cioè mi faccio dare da Alice il MAC di u, che sarà uguale anche al MAC di v, in questo modo avrò ottenuto il MAC per un messaggio che Alice non ha mai visto. Notare che non è stata fatta nessuna ipotesi su ek, che può anche risultare perfetta, eppure sono riuscito a effettuare una forgiatura, questo però al costo di conoscere q coppie valide. Quanto deve essere grande q per rendere impossibile la forgiatura, ci viene detto dal legame tra la q e la probabilità che questo (conoscere q coppie) accada. Viene fuori che si può ritenere che l’attacco avrà successo se q≥[1+√(1+8·2tlog(2))]/2 dove 2t è il numero dei possibili MAC, l’attacco riesce con probabilità maggiore di ½ se q è maggiore di una quantità che va come 2t/2 , cresce esponenzialmente con il numero di bit di MAC.

ESER. 01 – 17/10 Aspetti realizzativi della crittografia simmetrica

Terminato l’argomento dei meccanismi crittografici, con relative semplificazioni per la crittografia simmetrica, cioè quella a chiave segreta condivisa, vediamo alcuni aspetti che riguardano l’implementazione e l’uso pratico di questi meccanismi. Innanzitutto quando si parla di crittografia “Forte”, si intende l’uso di quei meccanismi crittografici ritenuti ad oggi non rompibili con l’utilizzo delle risorse disponibili. Ad esempio usare AES con una chiave a 128 bit è ritenuto oggi un crittografia forte, non perché si sia dimostrato che non sia possibile romperlo, ma perché nessuno ha trovato un attacco efficace, e l’attacco a forza bruta è assolutamente infattibile. Qual è un punto ricorrente tipico di debolezza? È possibile affermare che ormai il software è la parte di gran lunga prevalente di ciò che compone le reti di telecomunicazioni. Un dato di fatto poi, ad oggi accettabile, è che il software, in tutte le sue realizzazioni, ha errori. Si ritiene quindi accettabile un software che nelle normali condizioni operative, sia privo di errori al 99,99%. Da un punto di vista della sicurezza però questo non va bene perché, anche se un uso normale del software non consente di rilevare quell’1% di errore, la strategia di un attaccante prevede proprio la concentrazione della propria attenzione su quell’unico punto critico, facendo in modo che le interazioni col sistema che ha quella vulnerabilità, siano tali da andare tutte a cascare su quella vulnerabilità. Una delle vulnerabilità ricorrenti riguarda la tecnica del cosiddetto Buffer Overflow che fondamentalmente si realizza in questo modo. Un codice per essere eseguito viene caricato in uno stack, dentro il Sistema Operativo (SO), nel quale vengono allocati codice e dati di programma. Quel che succede è che a seconda del SO e della gestione, questi dati di programma e codice utilizzano spazi anche vicini all’interno dello stack. Se non vengono fatti controlli di range, avviene che ad esempio si dedica una certa quantità di buffer, all’interno dello stack, per memorizzare un indirizzo piuttosto che un campo di un messaggio in entrata, ma se questo campo è malformato o ha un uso non prevedibile, ciò che può fare l’attaccante è mettere al suo interno qualcosa che inizialmente appare come dovrebbe essere, ad esempio un URL, ma che in realtà è un codice macchina che verrà memorizzato. Il SO a questo punto, andrà ad eseguire qualcosa che è stato scritto laddove non era prevista la presenza di

Page 33: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 33

codice eseguibile. L’idea base del Buffer Overflow quindi, è creare dei campi particolarmente lunghi in modo tale da essere memorizzati nell’area di programma, in una maniera non casuale, caricandoci dentro un codice macchina che è quello voluto, che altera il comportamento del codice macchina. Esistono delle soluzioni a questi tipi di problemi (vedi le patch di SO che vengono rilasciate) la maggior parte delle volte però non vengono applicate (ad esempio non vengono installate le patch) quindi rimangono dei bug nel sistema. Uno degli aspetti pratici da tener presente è che sia i meccanismi crittografici, sia i vari protocolli, al momento della loro esecuzione, sono portati a memorizzare una serie di dati. Esiste quindi il problema della memorizzazione, su memorie volatili o statiche, di informazioni rilevanti per la sicurezza. Ad esempio vorrei che la memorizzazione di una chiave, avvenga innanzitutto in un’area a cui accedono soltanto quei programmi che sono autorizzati a farlo, in secondo luogo quando il programma ha cessato di essere eseguito, se quell’area è condivisa o non fisicamente protetta in qualche modo, il dato deve essere cancellato. La soluzione non è banale, e al solito è un compromesso tra livello di sicurezza che si vuole ottenere e costi. Un altro aspetto pratico poi è l’eliminazione delle informazioni dai dischi rigidi, in quanto la maggior parte dei SO mantiene comunque una memoria dei dati cancellati all’insaputa dell’utente. Per essere sicuri della cancellazione di un dato, bisognerebbe conoscere l’indirizzo di memoria in cui è allocato il dato e sovrascrivere la memoria stessa. Riguardo ad altri aspetti che hanno a che fare con la Network Security, possiamo aggiungere che la cifratura può essere applicata a livello di collegamento o da estremo a estremo. Link Encryption: ha di buono che ha il massimo grado di confidenzialità possibile, tutto ciò che finisce su quel collegamento, indipendentemente da chi sia la sorgente e chi il destinatario, verrà tutto cifrato. Ha di negativo che devo disporre di algoritmi cifranti e decifranti ai capi di ogni singolo collegamento e devo far condividere chiavi segrete per poter permettere questo a tutte le coppie di apparati ai capi di ogni singolo collegamento. Quest’approccio ha un impatto elevato su chi gestisce le reti ma che può essere anche nullo per chi gestisce le macchine terminali. End to end Encryption: significa che tutte le coppie di macchine interessate a comunicare in maniera confidenziale, debbono preventivamente condividere una chiave, quindi questo allevia e di molto l’onere di gestione delle chiavi da parte della rete, soprattutto se il livello dell’estremo-estremo è l’applicativo. In questo modo si sposta il problema sugli utenti finali, a cui viene delegato l’onere di concordare le chiavi. Ricordando la struttura a livelli del modello OSI o di TCP/IP, la cifratura può essere applicata a diversi livelli. Avviene che man mano che ci si sposta dal basso verso l’alto cambiano due cose, la prima è che il livello di aggregazione del traffico diminuisce, in altre parole si applica cifratura ad un flusso sempre più selettivo di traffico, la seconda cosa riguarda ciò che effettivamente si andrà a cifrare.

Page 34: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 34

Per la cifratura a livello applicativo (o https), un esempio è PGP dentro le e-mail, ciò che viene cifrato è al massimo il contenuto del payload del TCP, il contenuto informativo. Se invece la cifratura è ad un livello più basso, ad esempio a livello trasporto, all’interno di un collegamento o di un nodo (router) verrà cifrato il payload più l’intestazione TCP. Ma se il pacchetto viene letto all’interno di un gateway allora lo vedrò tutto in chiaro poiché il gateway deve risalire fino al livello applicativo per gestire il pacchetto. Se si scende ulteriormente di livello sempre più intestazioni vengono cifrate ma questo vale per un numero sempre minore di circostanze, cioè se la cifratura è a livello di Data link, l’intestazione del data link è in chiaro, ma tutto il resto viene cifrato, ma questo avviene solo sul collegamento. All’interno del router o del gateway troveremo tutto in chiaro, man mano che si scende quindi si cifrerà di più, ma sono anche di più i posti dove vengono gestiti in chiaro i pacchetti. Ecco perché i meccanismi di cifratura vengono applicati più volte e a diversi livelli di sicurezza, così ogni attore che sia il router o il gateway può decifrare solo l’info di cui ha bisogno. È possibile effettuare quella che si chiama Traffic Analysis, reperire cioè soltanto alcune delle informazioni relative ad una comunicazione, magari senza arrivare alla conoscenza del messaggio vero e proprio che due entità si sono scambiate, violando comunque il rispetto della confidenzialità. E questo è possibile a causa di quanto esposto prima sull’applicazione della cifratura ai vari livelli applicativi. Un modo molto semplice di contrastare la Traffic Analysis è fare il Traffic Padding. Io ho un flusso di pacchetti che porta dentro un suo fingerprint, perché generato da una certa applicazione, in quanto possiede un certo contenuto informativo, quindi determina sia quando arrivano i pacchetti, sia quanto sono lunghi, sia l’interazione tra le due parti. Per cercare di oscurare tutte queste informazioni, il Traffic Padding cosa fa, quando ho pacchetti da spedire mando quelli, quando non ne ho, ne mando comunque ma di fasulli, pacchetti che verranno scartati a destinazione, ma che dovranno corrispondere a pacchetti realistici. Tutto ciò al costo di un continuo traffico in emissione. (Simile alla Steganografia: immissione di poca info utile in tanta inutile). Parliamo ora di Random Numbers (Numeri casuali) cosa ci si fa e perché sono tanto utili nella crittografia.

Page 35: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 35

Servono per esempio per generare chiavi di sessione, piuttosto che le chiavi di lungo termine, per generare Keystream per i One Time Pad o meglio ancora dei Nonce. In tutti questi casi, per quanto riguarda la sicurezza, è importante che questi valori random siano:

- statisticamente casuali: cioè una sequenza di 0 e 1, per essere puramente casuale deve far si che la probabilità di apparizione di 0 e 1 sia la stessa (simboli equiprobabili); la probabilità di avere consecutivi n 0 o n 1 sia uguale a 1/2n per ogni n; le sequenze di 0 e di 1 osservate abbiano indipendenza statistica o più semplicemente autocovarianza nulla.

- impredicibili: cioè per quanti bit io abbia già visto, non debbo essere in grado di predire il prossimo bit che uscirà con probabilità maggiore di ½.

[ Entropia di una sorgente, nel senso della teoria dell’Informazione (Shannon): il numero di bit con il quale posso comprimere una sequenza prodotta da quella sorgente. È una quantità di bit irriducibile. ]

ESER. 02 – 18/10 – PRNG Crittografici

Dopo una breve introduzione sulla necessità di sorgenti di numeri random o meglio ancora pseudorandom, in un computer e possibile osservare una serie di sorgenti di casualità dalle quali estrarre bit casuali con un certo contenuto di Entropia, nel senso della teoria dell’informazione. Tali sorgenti hanno a che fare in sostanza con attività di periferiche o parti del computer stesso.

Tutte queste sono sorgenti ritenibili casuali, nel senso che non tutti i bit da loro generati sono veri bit di informazione, ma ne contengono una certa quantità. Un problema relativo a queste sorgenti è che quasi sempre generano una quantità troppo piccola e soprattutto incontrollabile di bit utili per gli scopi di un meccanismo crittografico. L’idea allora è quella di avere a disposizione dei generatori di numeri pseudo casuali Pseudo Random Number Generator PRNG, ed avere delle sorgenti di vera casualità che servono per inizializzare ed eventualmente rigenerare lo stato interno del PRNG. L’obbiettivo del PRNG è produrre sequenze di bit che appaiano come statisticamente casuali, e che siano in più impredicibili, cioè non devono essere soltanto una buona approssimazione di una sequenza casuale. L’approccio crittografico allora consiste nel costruire una macchina a stati, il cui stato interno è l’informazione chiave attraverso la quale è possibile ricostruire l’intera sequenza. L’inizializzazione poi avviene con l’ausilio di sorgenti puramente casuali in modo che non sia noto il modo in cui vengono inizializzate, facendo poi evolvere questa macchina a stati, introducendo di tanto in tanto nuova casualità, per rigenerare la casualità dello stato interno. Questo per evitare che con il passare del tempo un attaccante possa acquisire informazioni e compromettere il generatore acquisendo lo stato interno, e poter così predire l’evoluzione della macchina. Un modo particolarmente semplice per generare una sequenza pseudocasuale è il Generatore Congruenziale (poiché usa le congruenze):

Page 36: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 36

Xn+1 = (aXn + c) mod m Si parte da un numero iniziale Xn, e l’uscita è un numero compreso tra 0 e m-1, utilizzando ad esempio una rappresentazione di numeri interi a 32 bit senza segno, l’uscita è un numero che al massimo è compreso tra 0 e 231-1, per opportune scelte delle costanti a, c, m, questa si comporta come una sequenza statisticamente casuale. Da un punto di vista crittografico però questo è inutilizzabile poiché, supponendo di conoscere l’algoritmo, e il valore di m, analizzando una serie di evoluzioni, potrei scrivere due equazioni lineari in cui le incognite sono a e c, le Xn sono i termini noti, ricavando così facilmente le mie incognite. Dal punto di vista statistico questo continua ad essere un generatore pseudocasuale, ma essendo predicibile risulterà inutilizzabile per fare keystream, generare chiavi o altro. In più le scelte di a, c, m, non sono comunque qualsiasi se vogliamo avere un buon generatore statistico, per esempio è opportuno che m sia un numero primo, e a deve essere un numero che non ha fattori comuni con m. Un altro generatore molto più sofisticato, buono crittograficamente, ma di uso soltanto teorico, è il Blum Blum Shub, il quale funziona nel seguente modo:

xi+1 = xi2 mod n si ha uno stato interno x che è un numero compreso tra 0 e n-1, dove n è matematicamente ottenuto come prodotto di due numeri primi p e q. In genere n=pq, con p,q=3 mod 4, e per funzionare crittograficamente p e q devono essere numeri almeno di 512 bit, cioè devono essere numeri primi dell’ordine di 2512, e quindi n deve essere un numero rappresentabile in 103 bit, cioè un numero dell’ordine di 21000. Si fa allora il quadrato dello stato interno, lo si riduce mod n e si ottiene l’uscita. Se n è rappresentato mettiamo con 1024 bit, l’uscita avrà lo stesso numero di bit, ma se prendo tutti questi 1024 bit e li uso come uscita del mio generatore, sto dando in uscita proprio lo stato interno, cosa assolutamente non buona. In realtà si può fare in maniera crittograficamente robusta, dando fuori soltanto alcuni bit, in particolare solo il bit meno significativo, cioè quello che mi dice soltanto se il numero è pari o dispari. In questo modo avrò una sequenza effettivamente random, fornita da un generatore che supera il test del next-bit, cioè non esiste un algoritmo polinomiale tale che si possa predire qual è il prossimo bit generato con probabilità maggiore di ½. In realtà questo generatore è perfettamente attaccabile se si è in grado di fattorizzare n, cioè dato n trovare i numeri primi, cosa fattibile che diventa computazionalmente infattibile se si prende un numero abbastanza grande. Allo stato dell’arte di oggi si ritiene che un numero di 1000 bit non sia fattorizzabile praticamente. Un difetto capitale di tutto ciò e che per generare un keystream questo non è il massimo dell’efficienza, in quanto genera un bit alla volta al costo di operazioni non semplici come il quadrato di un numero a 1000 bit. Soluzioni pratiche a tutto ciò partono dall’idea di base che una cifrante a blocco, se buona, genera fondamentalmente bit random, cioè un random mapping in realtà deterministico ed invertibile, che appare però come casuale per chi non conosce la chiave. Utilizzo ad esempio il Counter Mode:

Xi = EKm[i] un contatore che non si ripete, che utilizza una chiave segreta, e il cui stato interno è la coppia contatore-chiave segreta, aumento il contatore, cifro, e quello che ottengo possono essere ritenuti bit casuali. Un generatore per esempio standardizzato nella norma ANSI X9.17 (American National Standards Institute) è un generatore che si basa in particolare sullo standard Triple-DES, che ovviamente può essere rimpiazzato con un’altra cifrante a blocco, che prevede l’uso della cifrante a blocco con una chiave segreta costituita in questo caso da due chiavi K1 K2 da 56 bit. L’ingresso è costituito dalla chiave segreta, una stringa binaria rappresentativa del valore Data e Ora (Date-Time) ed un seed, un seme iniziale

Page 37: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 37

ciò ovviamente va inizializzato con sorgenti di casualità vera presenti nel sistema. L’uscita sarà composta da i 64 bit di uscita del triplo DES-EDE Ri, e il nuovo valore del seme Vi+1. Per evitare che un attaccante possa prima o poi ricostruire lo stato interno, è opportuno preventivamente fare un reseed completo di chiave e input. Un esempio più dettagliato di uno pseudocodice che genera una sequenza simile allo standard ANSI, è il seguente. Si utilizza una cifrante a blocco come mattoncino base del generatore, in questo caso AES con una chiave segreta a 256 bit, e un blocco di plaintext e ciphertext di 128 bit. Lo stato interno della nostra macchina è costituito dalla chiave segreta (256 bit), e da un contatore che non si deve mai ripetere (128 bit) che useremo come input nella cifrante AES. Dire che non si deve mai ripetere, vuol dire che si deve usare il codice per un numero di volte sufficientemente più piccolo di 2128. Inizializzazione:

Lo stato interno è la coppia chiave-contatore (K,C), inizialmente pari a (0,0), è importante inizializzare anche il contatore, poiché se C=0 vuol dire che il sistema non è ancora in grado di generare dati crittograficamente robusti. Reseeding, Inserimento del seme (reseed poiché verrà richiamata per aggiornare il seme):

In particolare, il contatore non si ripete mai, si inizializza una volta e poi si incrementa sempre di uno, la chiave invece viene rigenerata. Una soluzione possibile è che il nuovo valore di chiave venga dato dall’hash di una stringa ottenuta concatenando il vecchio valore di chiave ed una sequenza s che è il seme. In questo modo nella chiave sto introducendo la vecchia chiave, che potrebbe essere in parte o totalmente corrotta, e il seme s. Questo reseeding sarà efficace se e solo se s contiene un numero sufficiente di bit non predicibili, cioè una quantità sufficiente di entropia, che risulta essere accettabile se s contiene almeno 128 bit di entropia. Vediamo ora come si possono generare i dati casuali usando la cifrante a blocco di 16 byte, partendo quindi dalla generazione di un numero k di blocchi di dati random

Page 38: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 38

l’input è lo stato del generatore, e k il numero di blocchi voluti. Prima di tutto verifica che C≠0 poiché altrimenti vuol dire che il generatore non è stato inizializzato, dopodiché la stringa vuota r viene costruita appendendo per k volte l’uscita della cifrante con chiave K e plaintext C, cioè la cifrante AES usata in Counter Mode. Alla fine avrò una stringa di 16*k bytes casuali. Se invece voglio n byte con n intero qualsiasi, non necessariamente multiplo di 16, genero comunque byte casuali a blocchi di 16, ne genero di più e quello che è di più rispetto ad n li butto.

Bisogna innanzitutto verificare che n sia compreso tra 0 e 220 bytes, poiché è opportuno limitare il numero di blocchi generati dopo il quale si fa reseed. Tale numero di blocchi progettualmente è fissato a 216 che moltiplicato per 24, che è la dimensione del byte, mi dà il limite di 220. Il generatore allora genera un certo numero di blocchi di dati random ( n/16 e ne prende la parte intera superiore ceil) in modo tale che ce ne siano almeno n, prende i primi n e gli altri li butta, e questa rappresenta la sequenza casuale richiesta. Successivamente modifica anche la chiave, senza reintrodurre casualità quindi facendolo in modo deterministico, e genera quella che si chiama Sicurezza in avanti, cioè se anche l’attaccante riesce a catturare la chiave, sarà in grado di compromettere i prossimi dati prodotti, ma non è in grado di compromettere quelli già prodotti perché si è persa l’informazione della chiave che gli ha generati. È importante quindi effettuare il reseeding e introdurre nuova entropia. A questo scopo ipotizziamo che il sistema sia dotato di sorgenti di vera casualità che al massimo possono essere 256, in modo da poterle numerare ed etichettare usando 1 byte. Quando queste hanno un numero sufficiente di byte casuali, interrogano il processo PRNG e offrono questi bytes che verranno accumulati dentro un Pool. Per fare un progetto robusto questo Pool viene strutturato suddividendolo in 32 pool numerati da 0 a 31 gestiti in modo particolare. Le re inizializzazioni vengono fatte ogni volta che il pool di indice più basso P0 è sufficientemente lungo, cioè supera una certa lunghezza minima. Ogni re inizializzazione è numerata progressivamente con un contatore che non si ripete, e le sorgenti di casualità, ogni volta che hanno bytes casuali, li caricano in uno di questi 32 pool. La selezione del byte casuale invece avviene in modalità differente, data la r-ima reseed, per quella re inizializzazione si usano soltanto i pool tali che r è divisibile per 2i, con i=0…31. Questo perché, poiché le sorgenti di casualità riempiono i pool uniformemente, a parità di intervallo T, i pool ricevono la stessa quantità di entropia in media, nell’uscita invece io uso tanto più raramente un pool quanto più il suo indice è alto. Usare raramente un pool vuol dire lasciargli il tempo di accumulare entropia, un buon compromesso per riuscire ad accumulare bit di casualità nei pools e permettere di fare frequentemente reseed. Se faccio reseed ogni T sec, il pool Pi verrà usato ogni 2iT sec, e lo stesso

Page 39: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 39

riceverà 2iρT/32 bit di entropia, se ρ (bit/sec) è il flusso medio di entropia in ingresso ad ogni pool da parte del sistema. Il Tempo di Compromissione, cioè il tempo in cui il sistema è potenzialmente compromesso (poiché non sono riuscito a reinizializzarlo), è limitato superiormente dalla quantità 8192/ρ, ottenuta dalla condizione 128 ≤ 2iρT/32 < 256 in cui il pool Pi ha accumulato 128 bit di entropia, ma il pool Pi-1 no. Il tempo minimo per recuperare 128 bit di entropia da parte di un sistema ideale (condizione per dire che non sono più compromesso) è 128/ρ sec.

ESER. 03 – 19/10 – Elementi di teoria dei numeri e algebra

Vediamo ora una serie di definizioni e proprietà che sono largamente utilizzate dalla crittografia moderna, quella basata su chiave pubblica. Cominciamo col dire cosa si intende dicendo che un intero a divide un intero n, cosa che si denota dicendo che a è divisore di n. Un intero a divide un intero n se esiste un intero b tale che n=ab. Si dimostra che dati due interi qualunque a e b, si può rappresentare in maniera unica a sottoforma di a=qb+r, dove q è il quoziente per la divisione q=floor(a/b) (con floor = parte intera inferiore) e r e il resto, con 0≤r<b, strettamente minore di b e non negativo sempre.

Esempio: a=23, b=5: q=4 and r=3; a=–23, b=5: q=–5 and r=2

Fissato un intero g>1, si può rappresentare un qualunque intero in base g, cioè si può scrivere che l’intero a = a1gk +…+ ak–1g + ak, dove gli ai sono numeri interi tali che 0≤ai<g, e k=floor(logga)+1.

Si dice poi che una certa funzione f(x) è un O (o grande) di g(x), con f e g definite su X: f(x)=O(g(x)) se esistono due costanti B e C tali che per ogni x>B f(x)≤Cg(x). Cioè per x abbastanza grande, f(x) è maggiorata da una copia proporzionale di g(x), non cresce più velocemente di g(x). A questo proposito possiamo parlare di Complessità Computazionale: definiamo la dimensione di a, size(a)=floor(log2a)+1, che vuol dire l’ordine di grandezza di a in termini di notazione binaria, ovvero il numero di bit che servono per rappresentare l’intero a. Se diciamo che la complessità di addizionare un bit è O(1), cioè rappresenta la complessità elementare, unitaria, allora l’operazione a+b ha una complessità che è O(max[size(a),size(b)]), lo stesso per la differenza. La moltiplicazione ha una complessità pari a O(size(a)*size(b)), se gli operandi sono a n bit, la complessità del loro prodotto è O(n2), cresce come n2. Mentre per la divisione si ha una complessità pari a O(size(q)*size(b)) dove q è il quoziente e b il divisore. Si dice che un Algoritmo ha Complessità Polinomiale se: dati come input dell’algoritmo, n numeri interi z1,z2,…,zn, se l’algoritmo richiede per la sua esecuzione una complessità che è un

O([size(z1)]e1·[size(z2)]e2·…·[size(zn)]en) dove gli ei sono esponenti non negativi, allora si dice che

l’algoritmo ha una Complessità Polinomiale, cioè la sua complessità aumenta in maniera proporzionale ad una potenza della dimensione degli operandi. Tutto questo discrimina la fattibilità o meno di un algoritmo, risulta infatti fattibile tutto ciò che ha complessità polinomiale. Introduciamo ora il concetto del Massimo Comune Divisore (gcd: Greatest Common Divisor) di due interi a e b. Innanzitutto si dice che d è un divisore comune di a e b se lo è di entrambi, cioè esistono x ed y tali che a=dx e b=dy allo stesso tempo. Il gcd (a,b) ha la proprietà di essere l’unico divisore comune ad a e b che è diviso da tutti gli altri divisori, in più è 1≤gcd≤min(|a|,|b|) e non può essere inferiore ad 1, poiché 1 è un comune divisore, gcd è il massimo comune divisore quindi deve essere maggiore o uguale ad 1. Ad esempio il gcd(-20,14)=2. Cerchiamo di capire ora come possiamo risolvere le equazioni del tipo ax+by=n con x e y incognite, equazione che va risolta sui numeri interi, cioè a,b,n, sono numeri interi, ma vogliamo anche trovare soluzioni sui numeri interi. Cominciamo col vedere allora come, dati due numeri a e b, al variare di x e

Page 40: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 40

y nell’insieme di tutti gli interi, quale insieme viene rappresentato da ax+by=n. Per definizione so che questo insieme coincide con l’insieme di tutti i numeri che sono proporzionali al gcd(a,b)=> ax+by=cg, dove g=gcd(a,b). Questa equazione allora ammetterà soluzioni, quando n sarà un multiplo di g, quindi per quanto detto, l’equazione 5x+3y=n, ammette soluzione per ogni n dato che gcd(5,3)=1. Un algoritmo che calcola il gcd è l’algoritmo di Euclide:

dato a≠0: se b=0, allora gcd(a,b)=|a|, è il più grande intero che divide a e b; se b≠0, allora gcd(a,b)=gcd(|b|,a mod |b|) abbiamo detto che quando divido due numeri a/b interi, esistono e sono unici due numeri q ed r, quoziente e resto, compreso tra 0 ed |b-1|, allora per definizione r=a mod b= a – qb

un esempio di esecuzione di quest’algoritmo con a=1344 e b=44 è il seguente:

La complessità di quest’algoritmo è O(size(a)*size(b)), quindi è un algoritmo efficiente (poiché è polinomiale) ed ha complessità lineare nel prodotto degli operandi, si dimostra inoltre che il numero di esecuzioni per cui converge è pari a 1,44*size(b). Un algoritmo più interessante è l’algoritmo Extended Euclidean Algorithm (EEA) il quale invece di calcolare soltanto i resti, ignorando i quozienti, calcola il gcd e la rappresentazione del gcd nel seguente modo: dati due numeri a e b esistono x e y tali che valga la seguente ax+by= gcd(a,b); per k=1….n (con n numero di iterazioni di EA)

E si dimostra che x=(–1)nxn e y=(–1)n+1yn.

La sequenza dei resti dell’EA è rk–2=rk–1qk–1+rk, k=2,…,n, con r0=a, r1=b e rn=gcd(a,b). E’ immediato

verificare che rk=(–1)k xk a+(–1)k+1 yk b per k=0 e k=1. Arrivati al valore di k per cui rk+1=0, l’algoritmo

preleva il valore rk che coincide con il gcd, e i valori xk e yk che a meno del segno coincidono con quei valori di x e y tali per cui vale x=(–1)nxn e y=(–1)n+1yn, cioè ha calcolato anche la rappresentazione. Il

tutto ha una complessità che è uguale alla complessità asintotica dell’EA: O(size(a)*size(b)). Vedremo più avanti che questi numeri x e y serviranno per calcolare l’inversa moltiplicativa, che rappresenta uno dei passi fondamentali di RSA per la generazione della chiave. Altro capitolo importante è la Fattorizzazione dei numeri primi; un primo è un intero p>1 tale che sia divisibile per 1 e per se stesso. C’è un teorema elementare che dice che ogni intero a>1 ha un divisore primo, che si dimostra semplicemente: supponete che d sia un divisore di a e fra tutti i divisori di a, rappresentati da un insieme finito e non vuoto (1 e a ci sono sicuramente), ha senso definire il più piccolo dei suoi divisore che chiameremo proprio d=min{divisori>1, di a}≥1. Allora o a è un numero primo, e quindi il teorema è subito dimostrato in quanto a è divisibile per se stesso ed ha un divisore primo, se stesso. Se a non è un numero primo, posso affermare che il min dell’insieme dei suoi divisori è strettamente >1 in quanto non essendo primo deve avere almeno un divisore che è diverso da 1 e da se stesso, e quindi ha senso definire i divisori di a maggiori di 1. È facile dimostrare che d deve essere

Page 41: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 41

per forza un numero primo, perché se non fosse primo, posso fattorizzarlo e scriverlo come d=bc e questi fattori sarebbero anche divisori di a e per giunta sarebbero >1 e <d e questo non può essere perché per definizione d è il più piccolo divisore>1 di a. Una volta dimostrato questo, posso dimostrare il Teorema Fondamentale dell’Aritmetica cioè che qualunque numero intero è fattorizzabile in maniera univoca nel prodotto di potenze e numeri interi. Se x è un numero intero, posso sempre scriverlo come x=+1e1+2e2+…+pnn cioè esistono n numeri interi ed n esponenti positivi tali che x si può scrivere in questo modo, a parte il segno. Sempre Euclide ha affermato poi che ci sono infiniti numeri primi, ciò è dimostrabile supponendo per assurdo un insieme finito di partenza di N numeri primi p1,p2,…,pN . Dato q=p1p2…pN+1 esso è più grande di tutti i numeri primi, quindi o lui è un numero primo allora mi sono già contraddetto, oppure non è un numero primo, quindi avrà almeno un divisore primo che sarà uno dei pn, ma nessuno di essi può essere divisore, perché come si vede dà sempre resto 1, mai resto 0. Quindi è falsa l’ipotesi di partenza che esistano N finiti numeri primi. Soltanto un centinaio di anni fa invece sono riusciti a dimostrare qual’è un’approssimazione della legge con cui si distribuiscono i numeri primi. Indichiamo cioè con πN l’insieme dei numeri primi compresi tra 1 ed N, quindi πN tenderà ad infinito se N tende ad infinito, ma quanto velocemente? La densità dei numeri primi, cioè πN/N, tende a comportarsi asintoticamente come 1/logN. Tutto ciò è importante perché come vedremo ogni qualvolta bisognerà scegliere una chiave pubblica, bisognerà trovare dei numeri primi, e per dimostrare che un numero è primo bisogna dimostrare che non ha altri divisori all’infuori di se stesso ed 1. Poiché creare un numero primo a 1000 bit non è semplice, si pesca a caso un numero di 1000 bit e poi con degli algoritmi efficienti si verifica se è primo o meno. La probabilità di trovare un primo mi viene descritta dalla densità mostrata sopra. Andiamo avanti con la definizione di Gruppo. Dato un insieme G ed un’operazione • definita su G, per ogni a e b appartenenti a G esiste un numero z=a • b appartenente a G. Tale operazione è chiusa in quanto vale per ogni coppia a,b e il risultato appartiene sempre allo stesso insieme. Ora se G soddisfa le seguenti proprietà:

i) l’operazione soddisfa la proprietà associativa (x•y)•z=x•(y•z) per ogni x,y,z Є G; ii) esiste l’elemento neutro e Є G tale che x•e=e•x=x; iii) esiste l’elemento inverso x’ЄG tale che x•x’=x’•x=e

allora l’insieme G si definisce Gruppo. I gruppi a cui siamo interessati sono quelli generati attraverso le congruenze, in particolare ciò che ci è già noto, a=b mod m, si legge più propriamente a è congruo a b mod m, che equivale a dire che a-b=k*m, cioè la differenza a-b è multipla di m. Quindi dire che a,b sono congrui mod m vuol dire che la loro differenza è un semplice multiplo intero di m. Per esempio 3 e 13 sono congrui mod 10, cioè sono la stessa cosa a patto di multipli di 10. Fare la riduzione modulare vuol dire maneggiare interi compresi tra 0 e m-1. Fissato un intero m e la relazione di equivalenza a=b mod m, si partiziona l’insieme di tutti gli interi in Classi di Equivalenza; in particolare con m qualsiasi, la classe degli interi a=0 mod m, sono tutti i multipli interi di m, la classe degli interi a=1 mod m che sono tutti i (multipli interi di m) +1, la classe degli interi a=2 mod m che sono tutti i (multipli interi di m) +2, fino alla classe degli interi a=(m-1) mod m che sono tutti i (multipli interi di m) +(m-1). Quindi fissato un m, l’insieme di tutti i possibili interi rimane suddiviso in m classi di equivalenza disgiunte tra loro, rappresentate ognuna da un rappresentante di classe. Si possono definire le ordinarie operazioni di moltiplicazione e somma anche tra classi di equivalenza mod m. Prendiamo per esempio m=7, (3+6)mod7=9mod7=2 ho ridotto la somma modulo m. Per l’inverso della somma modulare si fa così: l’inverso mod m di 3 è? Il numero che sommato a 3 da m. Quindi 4 è l’inverso mod 7 di 3.

Page 42: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 42

Ciò risulta un po’ meno intuitivo con il prodotto, si fa sempre il classico prodotto, poi si divide per m e si prende il resto: (3*6)mod7=4. Per l’inverso invece dato un intero a nell’aritmetica modulare l’inverso è quell’intero a-1 tale che (aa-1)mod m =1: 3 è l’inverso(mod26) di 9 poiché (3*9)mod26=1. Quindi è facile affermare che non sempre esiste l’inversa e quando esiste bisogna capire come calcolarlo; l’esistenza o meno dell’inversa dipende da m, in particolare esiste l’inversa SSE il gcd(a,m)=1, cioè se a ed m sono primi tra loro. Gli insiemi dotati di somma e moltiplicazione modulare si indicano con (Zm,+,·), quindi possiamo scrivere Z8={0,1,2,3,4,5,6,7} ovviamente nella moltiplicazione c’è un elemento che non ha inverso, che è lo 0. Di tutti gli elementi non nulli però non tutti hanno l’inverso, ce l’hanno per esempio solo quelli che sono primi con 8, quindi i numeri dispari, 1,3,5,7, non esiste invece l’inverso di 2,4,6. Possiamo per ultimo affermare quindi che tutti gli a non nulli compresi tra 1 e m-1 saranno invertibili SSE m è primo quindi se prendo uno Zm con m primo saranno tutti invertibili tranne 0.

LEZ. 10 – 25/10 – Ordine in un gruppo, CRT. Introduzione alla crittografia PK

Ci ricolleghiamo alla lezione precedente ricordando che Zm è, negli interi, l’insieme delle Classi Residue modulo m, cioè quella partizione dell’insieme dei numeri interi che si ottiene considerando le operazioni di somma e prodotto mod un numero intero m>1. Per queste Classi valgono tutte le proprietà riguardo la somma, per quanto riguarda il prodotto invece valgono tutte le proprietà salvo l’esistenza dell’inversa, che non sempre è verificata. In particolare .

In base alla rappresentazione del massimo comune divisore, dati due interi a e b, esistono e si trovano mediante l’algoritmo di Euclide Esteso, due interi x e y tali che ax+by=gcd(a,b). Applicando questo risultato ad a e m, si avrà che ax+my=1 se m ed a sono tali che il loro gcd=1, allora posso trovare interi x ed y tali che vale ax-1=-my cioè che ax=1 mod m, a meno di multipli interi di m è uguale ad 1. L’x per cui vale questa relazione è l’inverso di a quindi da questa ipotesi discende che , e che un modo efficiente per

calcolarlo è determinare i due interi x ed y tramite l’algoritmo di Euclide Esteso la cui complessità è un O delle dimensioni di a ed m. Ovviamente è facile vedere anche l’inversa, cioè se vuol dire che la differenza

cioè è un multiplo intero di m, e quindi , dove al primo membro ho una

combinazione lineare con coefficienti interi (a-1,k) dei due interi a ed m. Queste combinazioni lineari si possono sempre scrivere come c*gcd(a,m) con c che dipende dai due interi (a-1,k), e quindi si avrà

. I due interi al terzo membro dovranno essere allora pari ad 1 e poiché

interi in modulo non possono essere minori di 1, l’unico modo per rendere il loro prodotto pari ad 1 è che tutti e due siano pari ad 1, in particolare . E questo dimostra l’altro verso dell’implicazione, se

esiste l’inversa allora il =1. Detto questo si capisce anche sotto quali condizioni in Zm una classe

residua ammetta classe residua inversa. In particolare si definisce la Funzione di Eulero come l’insieme di tutti i numeri compresi tra 1 ed m

che sono primi rispetto ad m e , cioè la cardinalità di Pm dove

Ad esempio , poiché solo 1 e 3 sono primi rispetto a 4 (cioè numeri che danno con 4

un gcd=1), così come , solo 1 e 5 sono primi rispetto a 6. toccherà il

massimo, cioè sarà uguale a m-1 SSE m è un numero primo, in quanto un numero primo ha come fattori comuni soltanto se stesso, che qui è escluso, ed 1.

Page 43: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 43

Allora in Zm gli elementi che ammettono inversa moltiplicativa sono esattamente , perché ammettere

inversa moltiplicativa equivale a dire che l’elemento in questione è primo rispetto ad m, cioè

è CNES affinché l’elemento k ammetta inversa moltiplicativa. Indichiamo con l’insieme dei numeri

appartenenti a Zm che ammettono inversa moltiplicativa, che sarebbe l’insieme delle classi residue, quindi la cardinalità di quest’insieme è . Se m è numero primo, allora tutti gli elementi non nulli di Zm

ammettono inversa moltiplicativa, in altri termini (Zm,+,·) rappresenta un Campo e è il suo Gruppo

Moltiplicativo. Per questo spesso si usa Zp, cioè l’insieme delle classi residue mod p, dove p è un numero primo, in modo da garantire l’inversa moltiplicativa per tutti gli elementi non nulli di quell’insieme. Un altro concetto importante è quello di ordine. Dato un gruppo moltiplicativo dotato dell’operazione prodotto (G,*), prendiamo un elemento g del gruppo e facciamone le potenze g0,g1,… e così via. Se l’insieme è finito come ad esempio l’insieme delle classi residue da 1 a p-1, , con p numero primo, quindi classi

residue che ammettono tutte inversa rispetto alla moltiplicazione mod p, considerando le potenze successive, succederà inevitabilmente che gi=gj, arriverò al massimo a p-1 esponenti (da 0 a p-2). La

cardinalità sarà allora data da , e il fatto che gi=gj induce a dire che esiste un elemento n tale

che gn=1. Allora dato un gruppo moltiplicativo, si definisce Ordine n di un elemento g il più piccolo intero n, positivo, tale che gn=1, e se il gruppo è finito l’ordine esiste finito per ogni elemento, e data p-1 la sua cardinalità, sarà 1≤n≤p-1. In particolare, dato un elemento di ordine n, l’insieme S={ 1,g,g2,…,gn-1} è detto Sottogruppo generato dall’elemento g. Sottogruppo poiché valgono tutte le proprietà della moltiplicazione valide per il gruppo, ma non è un semplice sottoinsieme poiché è Chiuso, cioè se moltiplico due comunque due suoi elementi ricado sempre in esso. Infatti se faccio g2gn-1=gn+1=g poiché gn=1. Da notare che tutti gli elementi che hanno ordine massimo p-1, generano l’intero gruppo , e si chiamano Generatori del gruppo

. Esempio numerico: , prendiamo l’elemento g=3:

g0=1 g1=3 g2=9 mod 7=2 g3=27 mod 7 = g2 g1 = 6 g4=4 g5= g2 g3 =12 mod 7=5 g6= g5 g1 =15 mod 7=1

6 è il più piccolo intero positivo tale per cui g elevato a quell’intero faccia 1, quindi g=3 ha ordine massimo, in quanto p=7 e l’ordine poteva essere al massimo p-1. Posso quindi rappresentare, oltre che con le classi residue , ={30,31,32,33,34,35}. Un gruppo che ammette generatori, e che quindi viene

rappresentato per successive elevazioni a potenza, si chiama Ciclico, e i generatori si chiamano Elementi

primitivi. Non tutti gli elementi sono però primitivi, ad esempio per 1, il più piccolo intero n per cui 1n=1 è 1, quindi l’ordine di 1 è n=1. L’elemento -1 che generalmente rappresentiamo con p-1 ha il seguente ordine: (p-1)2=(p2-2p+1)mod p= 1 (è uguale a 1 a meno di multipli interi di p), quindi 2 è il più piccolo intero n per cui (p-1)n=1, quindi l’elemento p-1 ha ordine 2, e questo è valido per qualunque gruppo. Dato allora un gruppo , e dato un elemento g, può essere utile verificare se n è uguale all’ordine di g, ma

farlo nel modo visto ora non è assolutamente efficiente. In realtà un modo più efficiente per verificare che un elemento g sia di ordine n è accertarsi che gn=1, ma soprattutto che gn/q≠1, per ogni q, divisore primo diverso da 1, di n. Per esempio g=3 ha ordine 6, e ciò si sarebbe ottenuto verificando che 36=1, e che 36/2≠1, e 36/3≠1. Tutto ciò è però applicabile se e solo se so fattorizzare n, perché magari l’ho costruito prima, ad esempio se n è il modulo RSA. Si può vedere subito perché vale il Piccolo Teorema di Fermat che nella sua forma generalizzata sta alla base di RSA, e che afferma che preso con p primo, e preso un elemento a appartenente a , allora

ap-1=1 mod p

Page 44: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 44

qualsiasi elemento elevato a p-1, da come risultato 1. Il numero di elementi primitivi di è uguale a

, ovviamente se p è primo, p-1 non è primo, se non altro perché è pari. Se g è elemento primitivo di

, allora preso un qualunque intero a appartenente all’insieme, io lo posso sempre rappresentare come

a=gx mod p, allora avrò che ap-1=(gx)p-1=(gp-1)x=1x=1 mod p. Questo teorema si può generalizzare ad un insieme con m intero qualsiasi non necessariamente primo,

in questo caso allora aφ(m)=1 mod m ,

Questa regola contiene la precedente poiché quando m è primo, la funzione φ di Eulero vale proprio p-1. Infine una cosa utile soprattutto per definire algoritmi di attacco, è il Teorema del Resto Cinese CRT. Ho una collezione di n numeri interi a1,….,an e di n moduli m1,….,mn tali che valga la proprietà che

gcd(mi,mj)=1

si dice che I moduli sono coprimi tra loro, cioè presi a coppie primi tra loro. Con questi dati allora io scrivo un sistema di equazioni di questo tipo x=ai mod mi per i=1….n, e mi chiedo se esiste un x tale da verificare queste equazioni. Esempio: x= 2 mod 4 x= 1 mod 3 x= 0 mod 5 la soluzione esiste ed è unica se , definiamo allora nel nostro esempio:

m1=4, m2=3, m3=5 � m=4*3*5=60 ; M1=60/4=15, M2=60/3=20, M3=60/5=12 a questo punto

dove gli yi sono le inverse moltiplicative degli Mi, e precisamente yi Mi = 1 mod mi, che posso trovare efficientemente tramite l’algoritmo di Eulero Esteso. Per verificare la soluzione basta andare a fare

x=mod mi = aiyiMi mod mi =ai mod mi

nel nostro esempio numerico: 15 y1 = 1 mod 4 riduciamo mettendo 15 mod 4 = 3 3 y1 = 1 mod 4 = > y1 = 3 (quel numero che moltiplicato 3, mod 4, fa 1)

20 y2 = 1 mod 3 riduciamo mettendo 20 mod 3 = 2 2 y1 = 1 mod 3 = > y2 = 2

12 y3 = 1 mod 5 riduciamo mettendo 12 mod 5 = 2 2 y3 = 1 mod 5 = > y3 = 3 Dopodiché in base alla formula viene fuori:

x = (a1y1M1 + a2y2M2 + a3y3M3 ) mod 60 = 130 mod 60 = 10

Introduzione alla crittografia PK Il nuovo approccio alla crittografia, basato sull’utilizzo di una chiave pubblica è nato tra la metà e la fine degli anni ’70, essenzialmente per rispondere all’esigenza di semplificare in qualche modo il problema della distribuzione delle chiavi. La domanda che si posero riguardava la possibilità di permettere ad Alice e Bob di scambiarsi un contenuto informativo celandolo a terze parti, senza condividere alcun segreto. L’idea di base è schematizzata in questo disegno:

Page 45: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 45

Alice prende il contenuto del messaggio, lo chiude in un cofanetto con un suo lucchetto, di cui soltanto lei possiede la chiave, quindi ne Bob ne una terza parte possono leggere nulle. A questo punto Bob prende il cofanetto e vi aggiunge un suo lucchetto e lo rispedisce ad Alice. Allo stesso modo in questo secondo passaggio non si ha accessibilità da parte di terze parti. Ricevuto il cofanetto Alice non fa altro che rimuovere il suo lucchetto e rispedire il tutto a Bob. A questo punto Bob è in grado di togliere il suo lucchetto e leggere il contenuto del messaggio. Tutto ciò è servito a far si che nel canale insicuro non è mai transitata un’informazione aperta, e i passaggi si sono resi necessari perché sia Alice che Bob posseggono solo le chiavi dei propri lucchetti. Si sarebbero saltati alcuni passaggi se, invece di condividere una chiave segreta, Bob avesse fornito prima ad Alice uno o più dei suoi lucchetti, senza la chiave ovviamente. Se devo mandare un messaggio a Bob, prima mi faccio dare un lucchetto da Bob, così al momento in cui devo mandargli un messaggio, lo chiudo e lo invio. In questo modo sembra che non si sia semplificato un granché perché ho bisogno di distribuire i lucchetti, in realtà ho semplificato un paio di cose molto importanti. La prima è che il lucchetto è un oggetto che chiunque può avere, l’importante è farlo in modo che chiunque può prenderselo, studiarlo per anni ma senza carpirne la chiave. La rivoluzione sta nel fatto che la cosa che devo distribuire per proteggere i messaggi, non è un segreto. Il secondo aspetto importante è che il lucchetto può essere distribuito off-line, no nel momento in cui si comunica. Il tallone di Achille di tutto ciò sta nel fatto che in questo meccanismo non c’è nulla che mi dia la garanzia che quelli che ho siano proprio i lucchetti di Bob. Questa chiave pubblica che io sto utilizzando va quindi autenticata se voglio garantire sicurezza. L’idea quindi è riuscire a costruire una funzione di cifratura che io posso divulgare pubblicamente, senza che questo permetta di ricavare la sua funzione inversa, in realtà si impedisce la capacità computazionale di ricavare questa funzione.

LEZ. 11 – 31/10 – Crittografia a Chiave Pubblica - PK (Public Key) - RSA

Potenzialmente la crittografia a chiave pubblica serve ad attuare uno qualsiasi dei meccanismi necessari per i servizi di sicurezza, in pratica questo tipo di crittografia ha trovato un uso estensivo in due tipi di meccanismi, quelli utilizzati nella distribuzioni di chiavi, e quelli utilizzati per autenticazione. Lo strumento utilizzato per l’autenticazione nella crittografia a chiave pubblica si chiama Firma Numerica. Per quanto riguarda la cifratura, nello scenario in cui Alice scrive a Bob un messaggio, Alice deve cifrare e Bob decifrare, in questo contesto Alice deve usare la chiave pubblica di Bob. Chiunque può cifrare un messaggio diretto a Bob, ma solo Bob può decifrarlo poiché per decifrarlo c’è bisogno della chiave privata. Per apporre una Firma Numerica invece, se Alice vuole autenticare un messaggio che invierà poi a Bob, dovrà usare la propria chiave privata per autenticare il messaggio. Chiunque altro, Bob compreso, per verificare la firma, deve usare la chiave pubblica di Alice, è questo perché chiunque deve poter verificare una firma, ma solo Alice deve poterla apporre. Parlando di cifratura nella maniera più semplice, io ho una funzione che trasforma un testo in chiaro in testo cifrato, utilizzando un parametro, la chiave pubblica. C’è poi una funzione che inverte questo processo, dato il testo cifrato mi restituisce il testo in chiaro, utilizzando altri parametri, la chiave privata. Si capisce che quello che serve è determinare una funzione invertibile (matematicamente parlando), perché

Page 46: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 46

altrimenti la cifratura non funziona, ma che in realtà si possa rendere praticamente non invertibile (ho bisogno di particolari conoscenze). Queste funzioni si chiamano One Way Function, a volte anche chiamate Trap-door Function, perché sono One Way se non si conosce un trucco, una Trap-door. RSA è un crittosistema con un insieme di testi in chiaro ed un insieme di testi cifrati, tali insiemi corrispondono a Zn, l’insieme delle classi residue modulo n, con n numero intero maggiore di 1, cioè l’insieme che noi rappresentiamo con gli interi 0,1,..,n-1. Quindi un testo in chiaro e un testo cifrato vengono rappresentati da un numero intero compreso tra 0,1,..,n-1. Si tratta quindi di stabilire una corrispondenza biunivoca tra stringhe binarie e numeri interi. È chiaro che se i numeri sono compresi tra 0,1,..,n-1, la corrispondenza può essere resa biunivoca, cioè posso fare questa codifica senza ambiguità, per una stringa di lunghezza non maggiore di log2 n. Ci si chiede se questo sia un cifrario a blocco o a flusso. In realtà è un cifrario a blocco, dove il blocco è composto dai bit che vengono mappati sul numero intero. La chiave di questo crittosistema è composta da K={(n,p,q,b,a) dove n è un elemento derivato, che si ottiene moltiplicando due numeri primi p,q, e che viene chiamato Modulo RSA; b è un numero intero qualsiasi compreso tra 1 e Φ(n) tale da essere primo con Φ(n), funzione di Eulero che nel caso particolare in questione, poiché n è il prodotto di due numeri primi, sarà semplicemente Φ(n)=(p-1)(q-1). Il numero a si ottiene invece risolvendo la seguente: ab=1 mod Φ(n), e la condizione necessaria e sufficiente affinché esista questo numero a è che b e Φ(n) siano primi tra loro. Infatti a è pari a b-1 e b sarà invertibile se e solo se è prima con Φ(n), quindi la condizione è che si può scegliere b a piacere purché sia primo con Φ(n). Della chiave data allora, la parte pubblica è n,b e può essere detta a chiunque, mentre la parte privata è a, in effetti una volta calcolato a e quindi una volta generata la chiave, ci si può dimenticare di p,q. Cifratura. Dato un testo in chiaro, che è un numero compreso tra 0 e n-1, lo si eleva alla potenza b e si prende il modulo n: y=eK(x)=xb mod n, producendo così un numero tra 0 e n-1. Tale numero, funzione del testo in chiaro, è calcolabile nota la chiave pubblica n,b, l’unica cosa che resta da verificare è se il calcolo si possa fare efficientemente. Decifratura. La funzione inversa della cifratura è uguale strutturalmente alla funzione diretta, è cioè anch’essa un elevamento a potenza modulare. Si prende il testo cifrato, lo si eleva ad a questa volta, in maniera modulare, e questo vi restituisce x: x=dK(y)=ya mod n questo perché (xb)a = xtΦ(n)+1 = (x Φ(n))t x = x (mod n) essendo ab=t Φ(n)+1 cioè 1 più un multiplo intero di Φ(n). per poter affermare che ciò è utilizzabile crittograficamente, dobbiamo dimostrare che: entrambi i calcoli siano efficienti, e che se distribuisco in giro la conoscenza della coppia n,b, non deve essere possibile da questa conoscenza di n,b risalire ad a, la mia chiave privata. È scontato osservare che in realtà conoscendo n, io potrei fattorizzarlo per trovare i suoi due numeri primi p,q, in modo da ricavare Φ(n), e calcolarmi così l’inversa di b mod Φ(n). Trovare l’inversa è un calcolo efficiente, in quanto esiste l’algoritmo di Euclide esteso, quindi nota la chiave pubblica si potrebbe tranquillamente calcolare la chiave privata, a costo di saper fattorizzare il numero n. Tutta la sicurezza poggia quindi su un duplice assunto: non esiste nessun tipo di attacco se non quello consistente nel fattorizzare n (attacco a forza bruta), e in secondo luogo non esiste nessun algoritmo polinomiale, quindi efficiente, per la fattorizzazione di n. Quindi per evitare un attacco del genere su RSA, si prendono p,q, abbastanza grandi (abbastanza grande oggi vuol dire un n di 1000 bit, cioè fattori primi di almeno 512 bit) da rendere infattibile la fattorizzazione, approfittando del fatto che la complessità dei migliori algoritmi di fattorizzazione non è polinomiale, ma cresce più rapidamente del polinomiale. In che modo si usa allora RSA, per prima cosa bisogna generarsi i parametri della chiave, si generano quindi due numeri primi p,q dello stesso ordine di grandezza, dopodiché si calcolano n=pq e Φ(n)=(p-1)(q-1). Si sceglie poi un b qualsiasi, a caso oppure con una scelta fissa, purché sia compreso tra 1 e Φ(n), e sia primo con Φ(n), cioè invertibile, in questo modo posso quindi invertire b ottenendo così a. A valle di tutto ciò, per utilizzare il cifrario avrò bisogno solo di b,n,a, quindi p,q,Φ(n) possono essere cancellati definitivamente. Per quanto riguarda l’efficienza delle operazioni modulari, ad esempio la moltiplicazione x*x mod n, si richiede un tempo che è un O(k2) con k=size(n) cioè il numero di bit che compone n, quindi la

Page 47: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 47

moltiplicazione modulare di due interi, ha una complessità che cresce asintoticamente con il quadrato del numero dei bit del modulo. Quindi il calcolo è efficiente perché cresce con il quadrato del logaritmo del modulo, e il logaritmo è una funzione molto lenta. L’elevamento a potenza si può effettuare con l’algoritmo di Square & Multiply, secondo cui xc mod n si può ottenere nel seguente modo: c è un numero che posso rappresentare in forma binaria, supponendolo composto da s bit cs-1…c1c0, allora si ha che

Ciò richiama l’idea di qualcosa che sia ricorsiva, faccio l’esponente di un numero ci di cui conosco i bit, e i bit sono sempre uno in meno di prima, ed essendo in numero finito questa ricorsione ha una fine. L’algoritmo è il seguente:

In realtà esegue il calcolo al contrario, si parte dalla parentesi più interna che è la si eleva al quadrato

e poi la si moltiplica per , per questo Square & Multiply. Il punto è che gli c sono dei numeri binari, 0 o

1, quindi elevare a 0 mi da come risultato 1, mentre elevare ad 1 mi da invece se stesso, quindi in realtà questi elevamenti a potenza si realizzano con dei test binari, degli if su un bit. Se il bit è 0 il risultato è 1, se il bit è 1, il risultato è x. Tutto ciò è efficiente in quanto viene fatto per s volte un quadrato ed un prodotto, poiché la complessità del prodotto è un O del numero di bit di n2 e quella del quadrato è la stessa, allora il tutto ha una complessità che è O(s* (log2 n)2), dove s è il log2 dell’esponente c, quindi la complessità risulta polinomiale nella dimensione (cioè numero di bit) dell’esponente, per la dimensione del modulo al quadrato. L’intero algoritmo risulta quindi polinomiale. Abbiamo quindi visto che il calcolo della cifrante di RSA è efficiente, quindi ha senso considerarlo come un meccanismo crittografico. Ciò che manca ora è affermare che effettivamente data la chiave pubblica non è possibile ottenere la chiave privata, cosa che si basa su due assunti: per fare ciò è necessario fattorizzare n, non esiste nessun’altra scorciatoia, e questo non è ancora stato dimostrato; l’altro assunto è che non esiste un algoritmo efficiente per fattorizzare gli interi, e anche questo non è ancora stato dimostrato. Il fatto è che su questi due assunti, avvalorati dall’esperienza, poggia la sicurezza di RSA, quindi fissati questi, per poter sconfiggere un attacco RSA è necessario scegliere i fattori p,q abbastanza grandi da rendere la complessità della fattorizzazione di n ingestibile. Negli standard RSA viene specificato non solo come fare la codifica e decodifica tra dati in forma binaria e numeri interi, che poi sono l’oggetto manipolato dalla codifica RSA, ma anche come formattare la stringa da fornire in pasto ad RSA, a seconda che serva per fare vera e propria cifratura, oppure una firma. Per fare una firma ad esempio la formattazione è la seguente:

Il primo byte è uno 0 (garantisce che il numero finale di questa stringa sia <n che è pari a 1024, che in binario ha il primo bit pari ad 1), poi un 1 (indica che si tratta di una firma, se c’è 2 indica che si tratta di cifratura), alla fine si inseriscono i dati in fondo. Il tutto deve avere una lunghezza maggiore o uguale a quella dettata dal campo di messaggio dentro al quale mettiamo il tutto. I dati sono ad esempio l’Hash di un messaggio, quindi se si usa SHA-1 ci saranno 160 bit (20 byte), segue poi un byte nullo, e successivamente almeno 8 byte tutti unitari ma che in realtà saranno tanti quanti ne servono per riempire il tutto (padding). Se si deve dare tutto in pasto ad RSA a 1024 bit, bisogna formare questi 1024 bit, nel seguente modo: 160

Page 48: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 48

bit = 20 byte rappresentano i dati (la vera e propria firma), poi c’è il byte nullo, in testa 0 ed 1, il resto saranno tutti byte unitari di padding. Questa stringa di 128 byte, mappata in un numero a 1024 bit, sarà dato in ingresso ad RSA. RSA lo trasformerà poi in un altro numero che convertito in stringa binaria rappresenterà la firma numerica. In questa formattazione, la cosa utile è quella di mettere nel padding (per padding si intendono tutti i byte

aggiunti a quelli relativi ai dati, quindi anche lo 0 ed 1 iniziali e il byte nullo prima dei dati) una struttura verificabile, in modo da rendere fattibile il controllo della firma, e creare dei vincoli alla manipolazione dei dati. Dalla matematica del problema ci si rende conto che in realtà l’unica cosa che importa è che a,b, siano inversi tra loro rispetto a Φ(n), o meglio rispetto ad un qualsiasi multiplo intero del minimo comune multiplo tra p-1, e q-1. Deve risultare quindi che a*b-1 sia un multiplo intero della quantità

(p–1)(q–1)/gcd(p–1,q–1) una possibile particolare scelta è prendere proprio Φ(n)=(p–1)(q–1). Pensiamo ora alla scelta dell’esponente pubblico b, e partiamo dalla condizione che sia 1<b<Φ(n), un numero qualsiasi random compreso tra 1 a Φ(n), purché sia primo con Φ(n), cioè gcd(b, Φ(n) )=1. Valori fissi di b rappresentano anche delle buone scelte dal punto di vista dell’efficienza e della praticità. Supponiamo infatti un b fisso pari a 3, a sarà quel numero intero tale che moltiplicato 3 farà 1 mod n, e verrà un numero abbastanza grande. Ciò significa che cifrare risulterà un po’ più efficiente che decifrare, perché cifrare vorrà dire elevare a 3, mentre per decifrare si farà lo square and multiply che richiederà più tempo. In uno scenario asimmetrico come quello della chiave pubblica è infatti logico spostare l’onere, la complessità, più su chi decifra che su chi cifra. Accade infatti che chi chiede dati cifrati crea la chiave pubblica e privata e fornisce la chiave pubblica a chi deve inviargli i dati, quindi è semplice cortesia che sia proprio il richiedente (colui che decifra) a fare il lavoro maggiore. In particolare 3 è il più piccolo esponente pubblico che si può usare, e va benissimo a patto che si faccia attenzione al fatto che i messaggi siano “piccoli”nel seguente senso: la cifratura in RSA è fatta come y=eK(x)=xb mod n, riflettendo sul significato aritmetico di questa operazione, ciò che maschera davvero i dati è la riduzione modulare, quindi bisogna fare attenzione che xb non sia minore di n altrimenti si distruggerebbe completamente la sicurezza del sistema. Poiché xb<n è tanto più facile quanto più è piccolo b, una delle controindicazioni nello scegliere b piccolo è che si faccia attenzione che il testo in chiaro non sia tale da fare accadere questo. Per quanto riguarda invece a, una volta scelto b, a è solo da calcolare, c’è un solo a che va bene, che è dato da b-1 mod Φ(n), la discussione quindi rimane sulla scelta di b. Va osservato però che data la chiave pubblica n,b, che bisogna assumere nota a chiunque, una qualunque delle restanti quantità che costituiscono la chiave K={(n,p,q,b,a) o meglio Φ(n) direttamente, è sufficiente per calcolare tutte le altre. Allo stesso modo se conosco a è possibile, ma meno ovvio, risalire a tutto il resto, in quanto si può determinare un algoritmo randomizzato che con probabilità maggiore di ½ trova in modo efficiente i fattori primi p,q. La durata di una chiave pubblica dipende dal contesto dell’applicazione, criteri generali dicono che le chiavi si logorano con l’uso, quindi più le uso più metto in giro materiale potenzialmente utile ad attaccare quella chiave. Altro punto da considerare è in quanti posti viene memorizzata la chiave, più sono più diventa vulnerabile. Il punto che rimane da considerare riguarda la possibilità di generare le chiavi pubbliche RSA, e cioè dei numeri primi che come abbiamo detto devono essere almeno di 512 bit.

LEZ. 12 – 02/11 – Generazione dei numeri primi e attacchi a RSA.

Ritornando all’ultimo punto non analizzato, cioè la generazione delle chiavi pubbliche RSA, quello che si fa non è altro che generare a caso un numero intero di 512 bit e poi si fa girare un test che asserisce se quel numero così prodotto è un numero primo o meno. Questa strada indiretta viene intrapresa perché non esiste un algoritmo efficiente per fattorizzare i numeri interi, e quindi non posso prendere un numero intero, cercare di fattorizzarlo e dire se è primo o non è primo.

Page 49: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 49

Per prima cosa vediamo come si genera un numero intero di k bit, compreso cioè nell’intervallo [2k–1,2k-1] scelto a caso. Si tratta in sostanza di generare k bit random, quindi ho bisogno di un generatore pseudorandom, ma per essere sicuri che il numero rientri in quest’intervallo, il bit più significativo va posto ad 1. Quindi di tutti i bit, il MSB e anche il LSB vengono posti ad uno, il meno significativo perché ho bisogno di un numero primo, che è ovviamente dispari. Quindi in generale quello che mi serve è generare a caso k-2 bit per ottenere un numero a k bit. Quindi l’elemento base da cui si parte per la generazione delle chiavi RSA è un generatore di numeri casuali, dopodiché si applica un algoritmo di primality testing. È noto a questi scopi, l’algoritmo di Eratosthenes per trovare i numeri primi, un algoritmo non efficiente in quanto la sua complessità non è polinomiale nel log di n, ma che permette di trovare tutti i numeri primi compresi tra 1 ed n.

Immaginate di scrivere i numeri interi partendo da 2 in quanto ci interessano i numeri primi. Allora si prende il primo numero della lista, in questo caso 2, e si cancellano tutti i multipli di questo. Poi si passa al successivo numero sopravvissuto dopo questa cancellatura, in questo caso il 3, e si riapplica l’algoritmo; questo iterativamente fino ad arrivare ad n. Quello che mano mano succede è che nella lista sopravvivono solo i numeri primi, il problema è che questo algoritmo non è efficiente.

Ci si chiede però se sia sensato generare i numeri primi secondo questo approccio, cioè prendere a caso k bit random e verificare poi se il numero è primo. In realtà questo approccio risulta sensato se, sono sicuro che in quell’intervallo esistono numeri primi (altrimenti cercherei il nulla), e se so che in quell’intervallo il la quantità di numeri primi non è piccola (altrimenti la ricerca potrebbe essere molto lunga). A questo viene in soccorso un risultato molto importante secondo il quale il numero dei numeri primi compresi tra 1 ed n, quando n�∞,risulta pari a n/log(n); ad esempio per k=2000, i numeri primi compresi tra 21999 e 22000 li ottengo sottraendo alla quantità dei numeri primi compresi tra 1 e 22000, la quantità di numeri primi compresi tra 1 e 21999. Quantità che ottengo con la formula appena vista n/log(n) che mi dice la quantità di numeri primi tra 1 ed n. Da questi calcoli si evince che scegliendo a caso un numero, ho probabilità 1/1386 circa, di pescare un numero primo tra i numeri compresi tra 21999 e 22000, che non è molto soddisfacente, ma serve ad osservare intanto che scegliendo i dispari intanto si dimezza la probabilità che scende ad 1/700 circa, in quanto escludo i numeri pari. Una prima cosa che si fa allora è verificare se il numero preso a caso ha dei divisori banali, cioè i primi divisori: 2, 3, 5, 7… un rapido calcolo che mi permette di escludere il 70% dei numeri scelti a caso. Dopodiché se il numero scelto non ha divisori banali, esistono due tipi di algoritmi, quelli deterministici e quelli randomizzati, in particolare di quest’ultimi vedremo l’algoritmo di MonteCarlo polarizzato al si (vuol dire che l’algoritmo risponde si o no, se risponde si c’ha preso, se risponde no, potrebbe aver sbagliato). Un esempio di algoritmo randomizzato già visto è l’algoritmo di LasVegas, tali algoritmi possono o terminare con successo, e allora danno la risposta esatta, oppure terminare con fallimento, cioè non danno la risposta. L’algoritmo di MonteCarlo invece, termina sempre, però può terminare con risultato corretto oppure sbagliato, e risponde alla domanda: dato un numero n questo numero è composto (non primo)? Esistono poi algoritmi molto più sofisticati di quelli che vedremo, che sono deterministici, non randomizzati, che vengono eseguiti in tempo polinomiale, e danno certamente la risposta esatta. Tanto per capire come funziona il test MonteCarlo, ne vediamo uno che non si può usare in quanto non è affidabile, il test di Fermat. Il teorema di Fermat dice che se p è primo, allora qualunque sia il numero a vale

Page 50: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 50

la seguente: 1≤a≤p–1, ap–1=1 (mod p), allora io prendo il mio numero candidato primo n, poi scelgo a caso un a, e questo è il motivo per cui il test è randomizzato, faccio an–1, e vedo se per caso questo numero mod n è diverso da 1, in quanto il test verifica se il numero è composto. Quindi se è diverso risponde si con certezza, è composto, ma se risulta uguale ad 1 posso dire forse è primo, non lo posso dire con certezza poiché quella nel teorema di Fermat è una condizione sufficiente. Si è dimostrato infatti che esistono dei numeri tali che non sono primi, e tali per cui per tutti gli a vale la proprietà ap–1=1 (mod p), tali numeri si chiamano Carmichael, e si dimostra che ne esistono infiniti, e quindi questo test risulta non affidabile. Una versione migliorata di questo test è il test di Miller Rabin, il quale dato n, che si suppone primo e dispari, prende n-1 che come tutti i numeri pari si può scrivere come n–1=2sd, con d dispari e s≥0. Quello che si fa poi è calcolare ad mod n, se questa quantità è uguale ad 1 si può concludere che n è primo, altrimenti si

calcola la seguante quantità: con 0≤i≤s-1, e verifica se questa quantità è pari a -1 o meno. Se è

uguale ad -1, allora n è un numero primo, se nessuna delle s-1 uguaglianze risulta pari a -1 allora n è composto. Il test di primalità può fallire se dalla scelta randomica degli interi escono fuori solo numeri composti. Il numero di primi nell’intervallo [2k-1,2k) per k>>1 è circa 2k/log(2k) - 2k–1/log(2k–1) ≈ 2k–1/(k·log(2)), quindi la probabilità che un numero random risulti composto è 1-1/k*log(2). Per garantire che la probabilità di fallimento sia inferiore ad ε, il numero di prove richieste è log(2k)*log(1/ε)≈1596*k*|log10(ε)|. Una volta che il candidato primo è stato trovato, il test di Miller Rabin è stato eseguito diverse volte, se il test conferma la primalità del candidato per t volte, la probabilità che il numero in questione sia davvero primo è almeno 1-1/4t. Detto ciò vediamo come possono essere portati avanti gli Attacchi ad RSA. Ci sono vari tipi di attacchi, quello più diretto è l’attacco che punta a catturare la chiave segreta, ma tutti gli attacchi pensati, passano sempre attraverso il medesimo profilo, cioè fattorizzazione del modulo RSA. In altre parole, sempre che il sistema non abbia altre falle, e tra quelle che abbiamo visto un possibile errore è quello di cifrare con RSA un messaggio che tradotto in un numero è così piccolo che il messaggio elevato a b è minore del modulo RSA: mb<n. in questo caso non ho scelto male la chiave, ma dovevo fare in modo che non accadesse quanto appena detto, cioè che fosse mb<n. Quindi salvo questi casi di uso sbagliato di RSA, tutti gli attacchi mai pensati si riducono comunque alla fattorizzazione del modulo RSA, quindi per parecchio tempo quello a cui si è pensato è stato trovare un modo efficace per fattorizzare n. Esistono quindi diversi algoritmi per fattorizzare, ne vediamo soltanto uno rapidamente, il più elementare. Tanto per avere un’idea di cosa fa, dato un numero n, supponiamo che p sia un suo divisore primo che non conosciamo, e supponiamo anche che io possa sempre fattorizzare p-1, in quanto numero intero. Posso quindi scrivere che p-1=x1e1* x2e2* x3e3*…. xrer, e supporre che tutte le xiei siano limitate da un certo numero b. Se supponiamo di avere un b tale che valga questa proprietà: xiei≤b, cioè che tutte le potenze prime contenute dentro p-1 siano limitate da b, allora p-1 è un divisore di b!=b(b-1)(b-2)(… fattoriale, allora dentro questi b fattori ci saranno anche le potenze prime di p-1. Da ciò discende la seguente operazione, si calcola a=2b! mod n con b noto, che ci permette di affermare che a-2b! è un multiplo intero di n, e siccome p è un fattore intero di n, esso sarà anche un multiplo intero di p. E quindi possiamo scrivere anche a=2b! mod p. Se b è stato scelto opportunamente, b! sarà un multiplo intero di p-1, quindi sarà un certo intero m che non conosciamo, per p-1: b!=m(p-1). Sarà allora a=(2m)p-1 mod p che sappiamo essere pari ad 1 secondo il teorema di Fermat, quindi a-1=(2m)p-1 mod p, a-1 è un multiplo intero di p. Abbiamo quindi scoperto che questo numero p che non conosco è divisore di n, perché abbiamo ipotizzato così, ed è divisore di questo numero a, che ho così calcolato, meno 1. Prendo allora le uniche due quantità che conosco, n,a, e ne faccio il massimo comune divisore, che dovrà risultare un numero multiplo di p, o p stesso, ma comunque un numero maggiore di 1. Il fatto che sia un numero maggiore di 1 mi fa capire che è la strada giusta verso la fattorizzazione, in quanto ho trovato un divisore comune, in particolare un divisore di n. Riuscirò a trovare un gcd>1, cioè riuscirò a fattorizzare n a patto di aver scelto b abbastanza grande, cioè quando sarà b>√n. L’algoritmo però avrà a questo punto una complessità che non sarà più proporzionale ad una potenza del log n, bensì sarà proporzionale ad n1/2, cioè non ha complessità polinomiale ma esponenziale (sempre rispetto a log n). Per sventare quest’attacco, e anche altri attacchi simili, devo fare in modo che p sia tale che dentro a p-1 ci deve essere almeno un fattore molto grande, e ciò si può ottenere ad esempio scegliendo p=1+2p1, dove p1 è un altro numero primo. In questo modo p-1=2p1 avrà solo due fattori, 2 ed un numero primo p1 che io

Page 51: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 51

scelgo apposta a 512 bit, e quindi mi sono garantito in maniera costruttiva, non a caso, che dentro il mio numero primo p-1 ci sia un fattore grande. Costruirlo in questo modo ha ovviamente un prezzo perché, oltre ad eseguire tutto l’algoritmo visto prima per cercare un p primo, bisogna poi verificare che anche (p-1)/2 sia primo, e quindi questo complica la ricerca. In questo modo però si è sicuri di aver costruito uno strong prime, cioè un primo tale che p-1 ha dentro un fattore grande. In pratica poi si usano algoritmi di fattorizzazione estremamente più complicati, il migliore dei quali ha una complessità sub-esponenziale O(exp((1.92+o(1))·(log(n))1/3·(log(log(n)))2/3)), cioè cresce esponenzialmente con il log n elevato a 1/3, cioè risulta inefficiente asintoticamente. L’efficienza o inefficienza asintotica vuol dire che se oggi risulta fattibile per un certo valore di n e io raddoppio n, se l’algoritmo è efficiente rimane fattibile, se invece è inefficiente raddoppiando n l’ho reso non fattibile (con aumenti modesti di n rendo non fattibile quello che oggi è appena fattibile). Poiché allora l’algoritmo di fattorizzazione non è efficiente, mentre quello di generazione delle chiavi lo è, raddoppiando il numero di bit di chiave, con un aggravio di complessità sostenibile riesco ancora a generare le chiavi in maniera efficiente, mentre rendo infattibile la fattorizzazione, almeno per ora.

LEZ. 13 – 07/11 – Attacchi a RSA, Crittosistemi a chiave pubblica alternativi ad RSA.

Continuando a parlare degli attacchi su RSA, in primo luogo troviamo l’attacco basato sulla fattorizzazione di n modulo di RSA, in questo modo l’attaccante punta a ricostruire la chiave privata RSA nota la chiave pubblica e eventuali altre informazioni. Abbiamo visto comunque che ad oggi non esistono algoritmi efficienti per fattorizzare gli interi, e quindi la contromisura di base per questo attacco è scegliere dei numeri primi p,q, che formano il modulo n, sufficientemente grandi da rendere computazionalmente infattibile la fattorizzazione. Ad oggi la soglia del sufficientemente grande è ritenuta dell’ordine dei 1000 bit. Questo per quanto riguarda un attacco generale su RSA mirante a catturare la chiave quindi a fattorizzare il modulo n. E’ possibile però portare attacchi più specializzati se ricorrono alcune condizioni particolari. Osservando la chiave privata sappiamo che la sua generazione avviene in due passi: si identificano due primi p,q abbastanza grandi con cui formare il modulo n, si sceglie poi b esponente pubblico con delle piccole restrizioni, e poi si calcola a l’esponente privato. Se viene compromessa la chiave privata allora, mantenere lo stesso modulo n e cambiare solo l’esponente b per ottenere una nuova a, ha delle controindicazioni, in particolare grazie alla vecchia chiave privata compromessa è più facile fattorizzare il modulo n. La regola base allora è che ogni singola istanza di RSA abbia i propri parametri, e se una chiave privata viene compromessa è bene generare tutti i parametri da capo. Un altro aspetto importante è che la chiave a non deve essere troppo piccola. E’ stato dimostrato infatti che esiste un algoritmo efficiente di tipo randomizzato tale che se gli interi p,q non sono molto distanti tra loro, e questo è il caso tipico di RSA in quanto vengono scelti in un range compreso tra 2k-1 e 2k, a avrà un numero di bit inferiore a n1/4/3, quindi data la chiave pubblica si riesce a fattorizzare n con probabilità maggiore di 1/2, e quindi ricostruisce la chiave privata a. Un altro tipo di attacco è il seguente, se si manda lo stesso identico messaggio a più utenti che utilizzano diversi moduli ni, ma lo stesso valore dell’esponente b, allora è possibile, intercettando tutti questi testi cifrati, utilizzare il teorema del resto cinese, con b equazioni in un’incognita che è mb. In questo modo si estrae la radice b-ima e si ricava il messaggio in chiaro. In pratica questo è interessante se b è relativamente piccolo, e il problema principale non è che si è usato lo stesso b con diversi moduli n, ma lo sbaglio sta nell’aver cifrato in questo modo lo stesso identico messaggio senza la minima variante tra un utente e l’altro. In questo caso l’attacco porta non a catturare la chiave privata, ma a decifrare un messaggio cifrato. Altra questione che riguarda b, è che una volta scelto un b e volendo cifrare un certo messaggio, bisogna fare attenzione che risulti xb>n, cioè nell’applicare RSA è fondamentale che l’operazione di riduzione modulare sia efficace. Altro problema: supponiamo di voler mandare un file cifrato molto lungo a un corrispondente con il quale non abbiamo una chiave simmetrica condivisa. Cifrare un file lungo decine di KB o anche MB, con cifratura a chiave pubblica è molto inefficiente, in RSA infatti con n di 1024 bit il blocco sarà di 128 byte, e quindi bisognerebbe cifrare molti blocchi, e per ogni blocco effettuare una cifratura RSA, cosa molto inefficiente. Quello che si fa quindi è cifrare per esempio con AES, in maniera estremamente più efficiente, il problema

Page 52: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 52

però è che la chiave simmetrica utilizzata va trasferita dall’altra parte. Quello che si potrebbe fare allora è prendere il file cifrato con AES, e poi assieme ad esso trasferire la chiave, con cui va decifrato, cifrandola con la chiave pubblica del destinatario, quindi con RSA cifrerò soltanto i 128 bit della chiave per il destinatario, e questo è fattibile con un solo blocco RSA. Il problema in questo caso è che il mio messaggio da cifrare è la chiave AES, cioè 128 bit, ponendo ad esempio b=3, scelta del tutto lecita, 1283 è un numero di 128*3=384 bit, facendolo poi modulo n che è a 1024 bit, non è possibile eseguire la riduzione modulare, quindi l’attaccante potrebbe prendere quello che si suppone essere la cifratura RSA e limitarsi a fare la radice cubica di quel numero che vede, ed estrarrebbe esattamente n. Per ovviare a questo problema basta prendere questi 128 bit, non così come sono, ma inserendoli in un blocco formattato come abbiamo già visto, byte 0, byte 1, padding e poi il resto; in questo modo si avrà un numero che elevato alla 3 sarà certamente più grande di n. Altro problema di RSA derivante dal fatto che RSA ha una struttura matematica molto regolare è il seguante. La cosiddetta proprietà moltiplicativa dice che se io ho due testi in chiaro m1,2, cifro ognuno di essi, il corrispondente cifrato di m1 è c1=m1b mod n, allo stesso modo c2=m2b mod n. Prendo adesso il testo corrispondente al numero (m1*m2)b mod n e lo chiamo c. Il testo cifrato c corrisponderà proprio al prodotto c=c1*c2 mod n, e questo non dovrebbe accadere poiché una buona cifrante appare, a chi non conosce la chiave, come un random mapping. Oltre a questi, si prendono in esame attacchi un po’ meno intuitivi, ma più basilari, che riguardano la Distinguibilità del testo Cifrato. Per Non Distinguibilità del testo Cifrato si intende dire che non esiste un algoritmo efficiente di soluzione del problema denominato Cyphertext distinguishability problem (CDP). In tale problema, data una funzione f: X�X di cifratura, tale cioè che l’insieme dei testi in chiaro è uguale a quello dei testi cifrati, si prendono due testi in chiaro x1,x2 e un testo cifrato y=f(xi) ottenuto cifrando uno dei due, e la domanda che si pone a chi deve risolvere il problema è se i=1 o 2, cioè quale dei due testi i chiaro è stato cifrato. Ora se l’attaccante può disporre di un Oracolo random che quando lui gli passa un testo in chiaro gli restituisce la cifratura, allora il problema diventa banale, a patto però che si tratti di un sistema di cifratura deterministico come quelli visti fin’ora, in cui cioè a parità di testo in chiaro in ingresso, esce esattamente lo stesso testo cifrato. Allora se la cifrante è deterministica, un attacco di tipo Chosen Ciphertext (con un oracolo disponibile riesco ad avere 2 testi cifrati da altrettanti testi in chiaro) risolve banalmente il problema. Al rovescio possiamo dire allora che se uno vuole una cifrante robusta anche rispetto ad un attacco Chosen Ciphertext, tale che questo tipo di problema non sia risolvibile in maniera efficiente, allora la condizione necessaria è che la cifrante sia Random, non può essere deterministica, oppure cambiando la chiave ogni volta che si cifra, il che vuol dire randomizzare la cifrante. Randomizzare è un modo generico per dire che devono cambiare le condizioni con cui viene eseguito l’algoritmo di cifratura ad ogni sua istanza. Se questo problema non si può risolvere in maniera efficiente, non esiste cioè un algoritmo polinomiale per risolverlo, si può dimostrare che il criptosistema per il quale questo problema è infattibile, ha Sicurezza Semantica. Pur conoscendo cioè coppie testo in chiaro testo cifrato, non acquisisco nessuna informazione sulla chiave. RSA come qualunque altro sistema deterministico non ha questa proprietà, occorre quindi considerare un estensione tale che per avere sicurezza semantica deve presentare la seguente struttura. Supponiamo di avere delle One way function, invertibili matematicamente a costo di conoscere qualche trapdoor, qualche parametro segreto, che mappano stringhe di k bit in stringhe di k bit. Abbiamo un’altra funzione G: {0,1}k �{0,1}m che modellisticamente è un random oracle, cioè un generatore random che dato in input una stringa di k bit, ne genera un casuale di m bit, con m che può essere più grande di k. Dato ciò, una cifratura semanticamente sicura si ottiene prendendo il messaggio x e mettendolo in xor con un keystream G(r) prodotto attraverso questo random oracle f(r), cioè un generatore di sequenze casuali, che ha un seme iniziale r. Dopodiché però poiché G(r) non è costruita a caso ma attraverso una funzione con un random seed (r), c’è la necessità che chi decifra abbia lo stesso seme per recuperare il testo in chiaro. Il passaggio di questo seme iniziale viene fatto in maniera sicura usando la cifratura mediante le funzioni one way f(r), per esempio con RSA. Il criptosistema sarà allora

P={0,1}m, C={0,1}k x {0,1}m e K={(f , f -1,G): f ЄF} E le funzioni di cifratura e decifratura saranno

Page 53: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 53

Chi deve decifrare allora prende y1 che è uguale ad f(r) e vi applica l’inversa f-1(y1)=r, ottenendo r, poi prende l’r lo manda in ingresso a G(r) ottenendo il keystream e lo mette in xor con y2, per restituire x. Il problema in questo caso è il seguente: abbiamo detto che le f(r) sono funzioni one way che mappano stringhe di k bit in altre di uguale dimensione, e se stiamo usando RSA k deve essere almeno di 1000 bit, quindi f(r) sarà una stringa di circa 1000 bit. L’xor tra G(r) ed x sarà lungo m bit e dipenderà da quant’è lungo il testo che voglio cifrare, che se sarà molto più corto di 1000 bit, verranno mandati ad esempio 1000 bit di overhead per cifrare 160 bit di testo in chiaro, cosa ovviamente molto onerosa. Una variante di questo, per renderlo più efficiente è la seguente: dato un testo in chiaro x ciò che produco cifrando è l’applicazione della funzione one way f di una stringa binaria fatta giustapponendo (||) due stringhe binarie.

y=eK(x) = f(y1||y2) La prima y1 è x mascherato cioè messo in xor con l’uscita di una funzione random oracle che ha come input un numero casuale r ad s bit: . Il valore di s viene scelto in relazione al livello di sicurezza desiderato, per esempio 128 bit.

La seconda stringa y2 conterrà l’informazione su r Quando dovrò decifrare allora prendo y e lo decifro conoscendo la chiave privata f –1(y)=z1||z2 dove z1,z2

sono le decifrature di y1,2 rispettivamente di m e s bit. Dopodiché da questa stringa di m+s bit, i primi m li mando in ingresso ad un hash e li metto poi in xor con gli ultimi s bit. Questo mi da r, lo mando in ingresso alla G(r) e metto poi il tutto in xor con i primi m bit della stringa z1||z2, tutto questo sarà uguale al testo in chiaro x. Quanto detto fin’ora risponde al nome di Optimal Asymmetric Encryption Padding (OAEP), ed è lo schema su cui si basa lo standard PKCS dell’RSA. Crittosistemi a chiave pubblica alternativi ad RSA.

Ci sono algoritmi di cifratura alternativi ad RSA ed utilizzati soprattutto nel contesto delle firme numeriche, che rappresentano un ultimo esempio di utilizzo di funzioni one-way, funzioni cioè invertibili ma la cui inversa si possa rendere computazionalmente non calcolabile a meno di non conoscere alcuni parametri. Di queste funzioni se ne possono trovare varie, ma solo due hanno trovato posto nella crittografia, l’esponenziazione xb mod n e il Logaritmo Discreto (DL). Il logaritmo discreto è così definito: preso un gruppo moltiplicativo G , un suo elemento αЄG di ordine n, che stà ad indicare che αn=1 mod n, ma αi≠1 mod n per qualunque i≠n, ed un elemento β appartenente al sottogruppo generato da α, il problema del logaritmo discreto è trovare quel valore di a tale che αa=β. Poiché a noi interessano insiemi fatti da numeri interi, qui si parla solo di numeri interi, α,β,a sono numeri interi, così come lo è il logaritmo discreto. In particolare poiché α è un elemento di ordine n, esso genera il sottogruppo, composto da n elementi, delle potenze successive {α}={ α0, α1 ,…, αn–1} con α0=1, e il problema ha soluzione solo se β appartiene a questo sottogruppo, inoltre i possibili valori del logaritmo discreto sono i numeri interi compresi tra 0 e n-1, quindi il problema è di natura finita. Il primo esempio di DL considera il gruppo Zp*, cioè l’insieme degli interi modulo p con esclusione dello 0. Le classi residue mod p, a parte la classe nulla, sono tutte invertibili mod p, e Zp* non è nient’altro che l’insieme delle classi residue mod p invertibili, tutte tranne la classe 0: x Є Zp*={1,2,…,p–1}. L’operazione che aggiungiamo a questo gruppo è il prodotto mod p. Dati allora due elementi α e β, a è quell’intero tale che αa=β, in particolare se per α scelgo uno dei possibili elementi primitivi del gruppo, cioè uno di quegli elementi che ha proprio ordine p-1, innanzitutto α di ordine p-1 mi genera l’intero gruppo, quindi il problema ha soluzione qualunque sia β. Inoltre si può riscrivere il gruppo di partenza con le potenze successive di α, { α0, α1 ,…, αp–2}, e quindi l’esponente a sarà 0≤a≤p–2. Il punto è che ad oggi non esistono algoritmi polinomiali per fare questo calcolo, trovare cioè a tale che valga l’uguaglianza αa=β, dato Zp*. Gli algoritmi esistono, il più efficiente ha una complessità sub-esponenziale, ma non è polinomiale, quindi non efficace.

Page 54: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 54

Per fare un altro esempio è possibile prendere il seguente gruppo: Zn, cioè l’insieme delle classi residue rispetto ad un intero n qualsiasi, quindi Zn={0,1,2,…,n–1}, con l’operazione di somma, l’elemento neutro ovviamente è lo 0. Attenzione, quando si ha a che fare con un gruppo, e si vuole fare αa, questo è uguale a dire αa= α° α° α° α, a volte, dove il simbolo “°” rappresenta l’operazione definita nel gruppo. Quindi nel gruppo Zn in cui è definita la somma come operazione, si ha che αa=aα mod n=β, perché io sommo a volte α, e quell’a tale che vale questo si chiama Logaritmo discreto di Zn. Possiamo facilmente dimostrare che la a che soddisfa ciò è a=α-1β, dove α-1 è l’inversa moltiplicativa di α. Quindi la soluzione esiste ed è unica se esiste α-1, e questo esiste se il gcd(α,n)=1, cioè se ho scelto come base del mio logaritmo un valore che è primo con n. Quindi la soluzione esiste ed è calcolabile in maniera efficiente in quanto l’unica cosa da calcolare è α-1, inversa moltiplicativa calcolabile tramite l’algoritmo di Euclide esteso. Ora, siccome il problema ha dimensione finita, per esempio in questo caso i valori possibili di a sono compresi tra 0 a p-2, allora se la dimensione di p è sufficientemente contenuta, posso attaccare provandoli tutti, in maniera efficiente. Più in generale l’attacco a forza bruta è l’attacco di tipo enumerativo, la cui complessità, dato un elemento α di ordine n, si calcola nel seguente modo. Si precalcolano tutte le coppie (i,αi), con i=0,…,n-1, e n ordine di α, questo perché le potenze successive di α, arrivate all’ordine n si ripetono. La complessità di questo calcolo è O(n) in quanto ripeto n volte l’operazione di prodotto, prendo poi il vettore che contiene tutte queste coppie e lo ordino secondo la seconda componente αi, e la complessità di questa operazione è un O(n*log(n)) poiché il vettore ha dimensione n. Dato poi β, il valore i tale che β= αi lo trovo facendo la ricerca sulla seconda colonna che ho ordinato, e questo mi richiede un numero di passi che è un O(log(n)), leggo poi la corrispondente prima componente ed ho trovato così il Logaritmo Discreto. La complessità di tutto questo è almeno un O(n) cioè è dominata dall’ordine dell’elemento α, quindi si rende non fattibile tutto ciò prendendo un α di ordine sufficientemente elevato. La complessità del più semplice algoritmo non enumerativo, che è l’algoritmo di Shanks, è un O(√n), che migliora ma non è comunque efficiente, cioè non è una complessità polinomiale rispetto al log(n). Altro algoritmo non enumerativo è quello di Pohling-Hellman, che ha una complessità che è un O(c√q) dove q è il più grande fattore primo di n e c è il suo esponente nella fattorizzazione. Questo algoritmo ci suggerisce che, nello scegliere l’elemento α che ha come ordine un certo intero n, bisogna fare attenzione che n contenga al suo interno almeno un fattore primo grande, perché se tutti i fattori primi sono piccoli, allora un attacco secondo l’algoritmo di Pohling-Hellman ha complessità fattibile. In pratica ad oggi per poter validamente utilizzare il calcolo del Logaritmo Discreto in Zp*, bisogna scegliere p di almeno 900, 1000 bit, e fare in modo che comunque dentro p ci sia un fattore primo di almeno 256 bit, questo garantisce contestualmente l’infattibilità di algoritmo come il Pohling-Hellman.

LEZ. 14 – 14/11 Crittosistemi a chiave pubblica alternativi ad RSA –

DL problem in ElGamal – Cenno alle ECC –Intro Firme Numeriche.

Continuiamo a parlare dell’utilizzo di algoritmi per definire crittosistemi a chiave pubblica in cui la funzione one-way utilizzata è il Logaritmo Discreto (DL). Bisogna quindi capire innanzitutto quali sono gli algoritmi più efficienti per il calcolo del DL, in quanto questi determinano il livello di complessità dell’attacco migliore che si può condurre ad oggi, e quindi determinano anche in definitiva la dimensione in bit dei parametri da utilizzare. Ricordiamo che in un sistema a DL bisogna definire la base del logaritmo nell’ambito di un gruppo. Un possibile gruppo molto utilizzato è quello indicato con Zp*, che sarebbe il gruppo moltiplicativo delle classi residue modulo p, dove p è un numero primo. Cioè quel gruppo che possiamo rappresentare, attraverso un rappresentante per ogni classe residua, con i numeri interi 1,2,…,p-1, quindi ha p-1 componenti, e l’operazione è (x*y)mod p. Per definire il DL in questo gruppo si fissa un elemento α, e si vanno a considerare elementi β ottenuti da αa mod p = β. Vedremo adesso un critto

Page 55: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 55

sistema in cui la chiave privata è il numero a tale che valga questo, mentre la chiave pubblica sono α,p,β. Definire quindi il DL in questo gruppo vuol dire specificare l’intero p e la base α su cui si fanno gli elevamenti a potenza e si definisce quindi il logaritmo. Si chiama logaritmo discreto poiché l’incognita in questo problema è l’esponente a, cioè dati α,p,β, calcolare a, cioè quell’esponente tale che αa mod p = β. Quando si parla della scelta della dimensione dei parametri, si sta parlando di p, in quanto α è un numero compreso tra 1<α<p-1, quindi è un numero dell’ordine di grandezza di p, che identifica la difficoltà risolutiva del problema, quindi bisogna capire quali sono i migliori algoritmi oggi esistenti per capire quanto grande deve essere fatto p. Vediamo allora come utilizzare questo DL per un critto sistema molto noto e di fatto utilizzato in uno standard molto diffuso che è il DSA, uno standard di firma numerica. Il critto sistema in questione è quello di ElGamal, un critto sistema a chiave pubblica in cui il problema del DL è ambientato nel gruppo (Zp*, *). Per questo gruppo il testo in chiaro è un numero di Zp* (P= Zp*), cioè come accade in RSA, i messaggi da firmare o cifrare sono numeri, e non stringhe di bit, quindi occorre avere una funzione che converta stringhe binarie in numeri e viceversa. Il testo cifrato quindi sarà una coppia di numeri in Zp* (C= Zp* x Zp*), e la chiave è fatta dalle 4 quantità K=(p,a,α,β), dove a è la chiave privata, mentre il resto è chiave pubblica. Queste 4 quantità non sono indipendenti tra loro e questi sono i legami tra di loro:

- Cifratura: y=eK(x,k)=(y1,y2), con y1=αk mod p e y2=xβk mod p

- Decifratura: x=dK(y)= y2(y1a)–1 mod p Siccome io pubblico e rendo disponibile a tutti le quantità p,α,β, e invece pretendo che a rimanga segreta, ovviamente mi stò basando sull’idea che pur conoscendo p,α,β, non si è in grado di calcolare a. In linea di principio questa cosa invece è fattibile, esiste un unico a tale che valga αa mod p = β, in quanto α è un elemento primitivo del gruppo, cioè un elemento di ordine p-1, che è il massimo ordine possibile in Zp*. Tutto il punto quindi sta nel rendere il computo di a infattibile praticamente, e ciò si ottiene scegliendo p dell’ordine di un migliaio di bit, e scegliendo a caso un elemento α che si primitivo. La funzione di cifratura allora prende in ingresso il testo in chiaro x, un numero Zp*, ed un numero k scelto a caso, compreso tra 1,….,p-1, quindi questo è un sistema di natura randomizzata. Si deve quindi, lato cifrante, estrarre un numero casuale k che si usa una sola volta per ogni cifratura, e la cifrante produce i due numeri y1,2 compresi tra 1,..,p-1, che appaiono come numeri casuali. L’idea che c’è dietro è semplicemente la seguente: y2 porta il testo in chiaro x mascherandolo attraverso la moltiplicazione per una costante random, mentre y1 porta l’informazione utile a chi riceve per rimuovere il mascheramento e recuperare x. In particolare chi riceve prende y1, lo eleva all’esponente privato che solo lui conosce, ne calcola poi l’inversa moltiplicativa che moltiplicata per y2 mi darà esattamente x. Dal punto di vista della sicurezza quindi, è pensabile usare questo sistema per crittografia nel senso che chi opera legittimamente fa operazioni efficienti mentre chi attacca fa operazioni inefficienti. E’ anche vero però che questo sistema è poco pratico per fare cifratura, in quanto necessità comunque di molti calcoli e molto overhead, tant’è vero che una sua versione semplificata è utilizzata per le firme numeriche ma non per cifratura. Per quanto riguarda la sicurezza che ha, il tutto si basa sul fatto che il logaritmo discreto non è fattibile, poi c’è una condizione molto importante che riguarda il modo in cui è definito ElGamal, cioè ogni volta che si cifra un nuovo testo in chiaro è necessario estrarre un nuovo valore di k, e mai riutilizzare lo stesso. Se per due volte si usa lo stesso k, non noto all’attaccante, accade che l’attaccante a quel punto non è più interessato ad αk, egli sa che y2=(xβk) mod p e che y2’=(x’βk), altro testo in chiaro x’ ma stesso βk, e qui commetto l’errore, ho usato per due testi in chiaro diversi, due cifrature diverse, lo stesso valore di k. A questo punto se prendo y2–1y2’=(βkx)–1(βkx’)=x–1x’ (mod p), se io conosco uno dei due testi in chiaro, conosco immediatamente l’altro, ho un legame che non dovrei conoscere, tra i due testi in chiaro. Notare che tutto ciò è possibile senza conoscere k, basta sapere che è stato usato lo stesso k due volte per due testi in chiaro differenti. Altro difetto è che si dice che ElGamal è Malleabile, cioè è possibile agire sul testo cifrato modificando il testo in chiaro. In particolare Alice cifra e produce la coppia y1,2 mandandola a Bob, in mezzo

Page 56: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 56

c’è Oscar che modifica y2 , che all’inizio è uguale a y2=xβk , in y2*m mod p dove m è un numero intero di sua scelta. Il risultato di questa sostituzione ha su Bob il seguente effetto: egli decifrerà m*x mod p e non ha modo di accorgersi di ciò sulla base di questo algoritmo, che non mi da nessun elemento per capirlo. Bisogna per forza prevedere qualcos’altro, come per esempio una struttura particolare all’interno del messaggio, o nel padding, o in maniera più esplicita utilizzare un MAC che però ovviamente mi produce più overhead. Diamo ora un cenno alle Elliptic Curve Cryptography (ECC), le curve ellittiche, che rappresentano un altro gruppo che ha trovato effettivo utilizzo. Va chiarito da subito che l’uso della crittografia a curve ellittiche ECC non porta a maggiore sicurezza, quindi a parità di sicurezza offerta, cioè di livello di infattibilità dei migliori algoritmi noti, quello che si è trovato è che gli algoritmi ECC sono generalmente più efficienti. Innanzitutto una Curva Ellittica è, nel campo reale, definita da equazioni di questo genere nel piano x,y: y2 = x3 + ax + b, dove x,y,a,b sono tutti numeri reali, quindi tutte le coppie x,y che sono soluzione di questa equazione, dati a,b, rappresentano una Curva Ellittica parametrizzata da a,b. Il grafico di una tipica Curva Ellittica è il seguente:

Si nota subito che per ogni coppia (x,y) che risolve l’equazione, anche la coppia (x,-y) è soluzione, in quanto y compare solo al quadrato, che è come dire da un punto di vista grafico che la curva è simmetrica rispetto all’asse delle x. In particolare al di sopra dell’asse delle x prendendo cioè le y positive, rappresenta la radice quadrata di un equazione cubica. Sui punti definiti dalle coppie x,y si può definire un operazione che è chiamata Somma di punti, ma non ha niente a che vedere con la somma che conosciamo. Dati due punti P,Q l’operazione è così definita: si prende la retta che passa per i due punti, la quale intersecherà la curva ellittica in un terzo punto (perché è una cubica). Ribaltando questa intersezione si intercetterà un quarto punto che per definizione è la Somma dei punti (P+Q). Clamorosamente questa operazione è un operazione di gruppo, è chiusa, esiste l’elemento neutro, esiste l’inversa. Dato P, l’inverso è quel punto P’ tale che P+P’ fa l’elemento neutro. Quello che interessa comunque sono le Curve Ellittiche definite su un gruppo finito, in cui cioè si prendono equazioni come quelle viste prima, ma i cui coefficienti e valori x,y,a,b non sono dei numeri reali, ma si muovono nel campo Zp, e le operazioni vanno intese mod p. Zp dotato delle due operazioni di somma e prodotto mod p è un campo, la cosa importante da notare è che stavolta il numero di

Page 57: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 57

punti della Curva Ellittica è finito, esiste un insieme finito di coppie possibili, che sono p2, alcune soddisfano le equazioni altre no. Rimane definita l’operazione di Somma di Punti in quanto date due coppie (x,y) che soddisfano questa curva ellittica su Zp la loro somma si ottiene applicando certe formule che permettono di calcolare le coordinate (x,y) del punto somma. Questa operazione si può dimostrare che definisce un gruppo che ha come elementi i punti della curva ellittica, cioè le coppie (x,y) che soddisfano l’equazione su Zp*. Il gruppo a su cui si applica tutta la teoria del Logaritmo Discreto è proprio questo, è il gruppo fatto dai punti della curva ellittica definita con coefficienti in Zp*, con l’operazione di Somma di Punti. L’algoritmo di ElGamal visto prima può essere ridefinito completamente su questo gruppo. L’insieme dei testi in chiaro sono gli elementi del gruppo Zp*, la chiave pubblica è la curva ellittica, la quale è parametrizzata attraverso 3 soli numeri il modulo p e i numeri a,b: Ep(a,b), detti questi 3 numeri ho detto tutto della curva ellittica in quanto ho detto sia il modulo del gruppo su cui sono ambientati i coefficienti, sia i coefficienti a,b stessi. Dopodiché la chiave pubblica è fatta scegliendo un punto P e il suo ordine n, l’ordine di un punto mi dice quante volte lo devo sommare per tornare a fare l’elemento neutro. Q poi si ottiene scegliendo un elemento m, che è la chiave privata, e facendo Q=m*P, cioè sommando P m volte, in quanto l’operazione “*” del gruppo è la somma di punti. Anche qui il problema del DL è infattibile, cioè a quanto si sa, per quello che è stato pubblicato, gli algoritmi migliori non sono efficienti poiché hanno una complessità che cresce più velocemente del log della dimensione del numero dei punti. In particolare quindi dati Q,P, teoricamente io potrei trovare l’unico m tale che valga Q=m*P, però in pratica non esiste nessun’algoritmo efficiente per farlo, in quanto trovare m significherebbe risolvere il problema del Logaritmo Discreto. Questo quindi assicura che la chiave segreta m rimarrà tale, anche se io pubblico Q,P e i dati della curva ellittica. Dopodiché la cifratura consiste nello scegliere a caso un kЄ Zn*, e poi invio kP e il testo in chiaro x moltiplicato modulo p per x0 che è la coordinata di Q:

y=eK(x,k)=(y1,y2)=(PCmp(kP), x·x0 mod p), con kQ= (x0,y0) and x0≠0 attraverso il punto Q scegliendo un k a casa costruisco un mascheramento, faccio kQ, quindi sommo k volte il punto Q, e questa è un operazione efficiente, ottengo una coordinata x0 che è random perché k è random, e la uso per mascherare il testo in chiaro. A chi deve decifrare poi do anche un modo per eliminare questo mascheramento passandogli kP, un punto che in realtà è ottenuto sommando k volte P. Chi decifra farà la seguente cosa:

x=dK(y,k)=y2(x0)–1 mod p , dove x0 è ricavato dalla prima parte y1del testo cifrato: m·PDcmp(y1)=mkP=kQ=(x0,y0)

prende quindi kP e lo somma m volte, mkP, ma mP per costruzione della chiave pubblica è proprio il punto Q, quindi ottengo in definitiva kQ senza aver bisogno di calcolare k, ma in realtà ottengo direttamente la coordinata x0 la cui inversa moltiplicata per y2 mi restituisce il testo in chiaro. Quindi chi decifra si limita a calcolarsi kQ che può fare in quanto a conoscenza della chiave privata m. Mentre un attaccante non può, dato kP ricavare k in quanto significherebbe risolvere un problema del DL. Ad oggi i migliori algoritmi noti per attaccare il problema del DL possono essere resi infattibili allo stesso livello di quelli su Zp* usando però un numero p di circa 300 bit, non 1000, con una enorme riduzione di complessità. Tutto quello di cui abbiamo parlato risponde al nome di ECIES, sistema crittografico basato sulle curve ellittiche. Parliamo ora delle Firme Numeriche, un altro meccanismo di sicurezza basato sulla crittografia a chiave pubblica che sono utilizzate per Autenticazione di entità o di messaggio e anche per supportare il servizio di non ripudio, cioè attribuzione non negabile di un messaggio. Abbiamo detto che Alice per inviare un messaggio cifrato a Bob, deve usare la chiave pubblica di Bob, mentre Bob per decifrare deve usare la sua chiave privata. Per firmare un messaggio, cioè per costruire una stringa che annessa al messaggio prova che il messaggio stesso è stato generato da Alice, quest’ultima deve utilizzare la sua chiave privata. Chiunque altro per verificare la chiave di Alice, dovrà usare la chiave pubblica di Alice stessa. Quindi è esattamente il corrispondente del MAC per la crittografia a chiave simmetrica. Adesso quindi non ci interessa più che il messaggio sia confidenziale o meno, il messaggio può essere anche pubblico, il punto è garantire che quel messaggio sia originato da una determinata entità, e che il messaggio sia conforme a quello firmato dall’entità, cioè non sia stato alterato. Tra i requisiti di cui

Page 58: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 58

bisogna tener conto in un sistema di firma numerica, quest’ultima deve dipendere dal messaggio che viene firmato, deve usare informazioni che solo il firmatario può conoscere, altrimenti la firma risulta imitabile, può usare informazioni di tipo temporali. Chi effettua la firma e chi la verifica deve eseguire calcoli efficienti pur rendendo computazionalmente infattibile l’imitazione della firma, infine la firma dovrebbe comportare un overhead limitato. Uno schema di una firma digitale quindi è caratterizzato da una quintupla (P,A,K,S,V), dove P è l’insieme dei possibili messaggi, stringhe binarie di qualsiasi natura, un insieme finito di possibili firme A, e già qui si nota la mancata corrispondenza biunivoca tra i due insiemi, quindi due messaggi diversi possono avere la stessa firma. C’è poi uno spazio delle chiavi K, e una coppia di algoritmi parametrizzati alla chiave, l’algoritmo di firma, che utilizzerà la chiave privata, e l’algoritmo di verifica che utilizzerà la chiave pubblica. L’algoritmo di firma mapperà un messaggio in una firma, quindi si tratta di una funzione non invertibile che da una stringa di messaggio arbitraria tira fuori una firma. L’algoritmo di verifica invece è un algoritmo che prende in input un testo e la corrispondente presunta firma e restituisce un’uscita che è binaria, vero o falso. In particolare si avrà vero se la firma è valida, cioè applicandolo alla coppia (messaggio,firma) lui mi darà vero quando la firma è ottenuta attraverso la trasformazione del messaggio con una funzione giusta, cioè se la firma è stata calcolata usando la corretta chiave privata applicata al messaggio. Per ogni kЄK, esiste una funzione privata di firma sigK Є S e una corrispondete funzione pubblica di verifica verk Є V, e per ogni sigK : P�A e verk : PxA�{vero,falso}, le seguenti equazioni sono soddisfatte per ogni messaggio xЄP e per ogni firma yЄA:

verK(x, y) = true if y = sigK (x) verK(x, y) = false if y ! sigK (x)

una coppia (x,y) con xЄP e yЄA e chiamata messaggio firmato, ed è detta coppia valida. Forgiare una firma cioè fabbricarla artificialmente vuol dire generare un messaggio x, e una stringa binaria y appartenente all’insieme delle firme, tali che la coppia (x,y) soddisfa l’algoritmo di verifica, cioè tale che sia una coppia valida. Va notato che per ogni data firma esistono diversi messaggi tali da costituire una coppia valida con quella firma. Una firma fabbricata quindi è una firma apposta su un certo messaggio x da qualcuno che non è il firmatario presunto, diciamo Alice, quindi indurre Alice a firmare un messaggio non è forgiatura di firma, ma un altro tipo di attacco. Metodi di forgiatura in ordine crescente di gravità sono:

- Fabbricazione Esistenziale: l’attaccante è in grado di produrre una coppia valida (x,y) senza però avere nessuna possibilità di influenzare il testo x.

- Forgiatura Selettiva: l’attaccante è in grado di produrre la firma di un messaggio da lui scelto, almeno in parte (c’è un solo particolare messaggio però).

- Totale Break: l’attaccante si impadronisce della chiave privata e quindi a quel punto può firmare qualunque cosa

LEZ. 15 – 15/11 Firme Numeriche.

La firma allora è un autenticatore di messaggio o di entità quindi uno strumento che serve a fornire garanzia di autenticità della provenienza di un messaggio ovvero anche di un’identità, e garanzia anche dell’integrità del messaggio stesso. In questo, l’impiego di una firma, è del tutto analogo a quello del MAC, con la differenza che qui siamo in un contesto a chiave pubblica, quindi analogamente al MAC l’attacco classico consiste nel fabbricare una coppia messaggio-firma valida, di un messaggio che però Alice non ha mai visto. Analizziamo ora i modelli di attacco partendo dal primo, quello base, Key Only, in cui l’attaccante non sa nulla fuorché quello che sanno tutti e cioè la chiave pubblica. Questo è ciò che tutti sanno, quindi è un attacco che non implica nessun’informazione aggiuntiva, c’è solo quella che ovviamente tutti potrebbero reperire, la chiave pubblica. Attacco Know Message, l’attaccante ha osservato una o più coppie valide senza

Page 59: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 59

poter scegliere che cosa far autenticare. Attacco Chosen Message, l’attaccante è in grado di procurarsi coppie valide con messaggi x di sua scelta, quindi l’attaccante può scegliere una collezione di messaggi x e indurre Alice a firmarli. In questo modo non ha ottenuto una forgiatura in quanto Alice ha firmato davvero i messaggi. In uno di questi contesti di attacco, l’attaccante può scegliere di eseguire uno dei metodi di forgiatura visti la lezione precedente. Vedremo ora due schemi di firma numerica, la Firma RSA e la Firma ElGamal, lo schema di firma è uno schema che definisce una coppia di funzioni di firma e verifica entrambe dipendenti da una chiave k. Per quanto riguarda la Firma RSA partiamo da una formulazione teorica, in realtà viene fatto in maniera differente. Ricordando esattamente a cosa serve una firma, consideriamo il fatto che non stiamo parlando di cifratura, non c’è confidenzialità, i messaggi possono viaggiare tranquillamente in chiaro. L’autenticatore è allora costruito in questo modo: la funzione che a partire da una chiave e dal messaggio da autenticare costruisce la firma, è questa:

y= sigK (x)=xa mod n

verK(x, y) = true if x=yb mod n verK(x, y) = false if x≠yb mod n

dove a è l’elemento segreto che costituisce la chiave posseduta solo da Alice. Qui siamo nel contesto RSA, c’è un intero n prodotto di primi p,q, due esponenti b,a, b è un esponente compreso tra 1 e Φ(n), a è il suo inverso mod Φ(n), n,b rappresentano la chiave pubblica, mentre a rappresenta la chiave privata. Chi verifica la firma riceve la coppia messaggio-firma e calcola la seguante quantità: yb mod n, cioè la firma elevata a b mod n, e questa cosa può essere fatta da chiunque. Se questa quantità risulta uguale a x la verifica è andata a buon fine, altrimenti dice no. La logica è che io calcolo la quantità yb mod n e mi torna uguale ad x, allora vuol dire che y è stato calcolato così: y= sigK (x)=xa mod n, e l’unico che può calcolarlo in questo modo, dato x, è l’unico che conosce la chiave privata a, e quindi quel messaggio è stato firmato da Alice, o da qualcuno che conosce a. Quindi come funziona la logica di una firma RSA, prendo semplicemente le due funzioni che ho definito per cifrare e per decifrare, faccio calcolare in questo modo la firma, dopodiché chi fa la verifica non fa altro che calcolare la “cifratura”, inverte la funzione di firma, se ritrova x vuol dire che y è stata calcolata così, e l’unico che poteva calcolarla è l’unico che conosce a. Se invece la firma non è stata calcolata così non ritroverò x e quindi giustamente dirò che il messaggio non è stato autenticato. Un problema nell’uso di RSA sta nel commettere l’imperdonabile leggerezza di usare la stessa chiave sia per cifrare che per autenticare. Se qualcuno mi chiede di autenticare un messaggio x, io calcolo y= sigK (x)=xa mod n, che è la funzione di firma RSA, ma che corrisponde anche alla funzione di decifratura RSA, quindi se uso la stessa chiave un attaccante potrebbe darmi un messaggio cifrato chiedendomi di autenticarlo, e così facendo io lo decifro. È necessario quindi utilizzare in ogni istanza di RSA delle chiavi diverse. Questo schema così elementare non funziona, in quanto è possibile intanto fare un attacco sulla sola conoscenza delle chiavi che porta ad una forgiatura esistenziale perché, preso un qualunque y il fabbricatore calcola la quantità yb mod n, ottiene un x, su cui non ha però nessun controllo di autenticità, e può così affermare che la coppia così ottenuta è valida. La cosa però che non va bene è che poiché RSA gode della cosiddetta proprietà moltiplicativa, succede che prese due coppie valide (x1,y1), (x2,y2), due coppie in cui la firma è calcolata così: y= sigK (x)=xa mod n, preso il messaggio x1*x2 mod n, la firma di questo messaggio è semplicemente y1*y2 mod n. Posso quindi fare un attacco di forgiatura esistenziale basato su conoscenza di coppie valide, forgiando una terza coppia valida distinta dalle altre poiché è il prodotto delle due, e di questa so calcolarne la firma. Se l’attaccante è ancora più potente e oltre ad osservare le coppie può scegliere cosa far firmare ad Alice, può fare un attacco di tipo Chosen Message, e fare a questo punto una fabbricazione selettiva e non più esistenziale. Dato ad esempio m il messaggio che l’attaccante vuol far firmare, si prende un messaggio m1 che tradotto in un numero intero sia primo rispetto ad m, poi prende m1 e se lo fa firmare da Alice ottenendo s1=m1a mod n. L’attaccante costruisce a questo punto il messaggio dato da m2=mm1-1 mod n e di questo messaggio ottiene di nuovo da Alice la firma s2=m2a mod n, a questo punto Oscar, a causa della proprietà moltiplicativa, può dire che la firma del messaggio m1m2 è s= s1s2 mod n. Per

Page 60: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 60

come è stato costruito m2, m1m2 non è nient’altro che m, il messaggio scelto all’inizio da Oscar, quest’ultimo è riuscito ad ottenere la firma di m date le due firme ottenute da Alice, senza che però Alice abbia mai visto il messaggio m. Un modo per ovviare al problema della proprietà moltiplicativa di RSA, che è poi il modo utilizzato nella realtà per applicare la Firma, prevede l’uso delle funzioni Hash; nella firma,al posto di x viene messo l’hash di x, h(x), y=h(x)amod n, funzione crittograficamente robusta. Oltre a risolvere questo problema poi, l’hash ci permette di firmare delle stringhe binarie di qualsiasi lunghezza, devo solo badare che l’hash sia di lunghezza binaria minore di n. Questo è ad oggi fattibile poiché gli hash più lunghi sono quelli a 512 bit di SHA-512, mentre n ha almeno 1024 bit, quindi certamente l’hash ha una lunghezza del tutto compatibile per fare questo calcolo. Se da un lato posso affermare di aver trovato un modo per evitare tutti gli attacchi visti fin’ora in quanto ho risolto il problema della proprietà moltiplicativa, l’uso delle firme tramite funzioni hash, ha sicuramente introdotto delle diverse vulnerabilità. Quello che si invia in questo modo è la coppia messaggio-firma (x,y), Alice firma un messaggio e lo manda a Bob, Bob per verificare il messaggio prende x, calcola senza problemi h(x) in quanto si usa una funzione hash pubblica, ad esempio SHA-1, e poi calcola yb mod n, e verifica che questo gli venga uguale ad h(x). Dico che la firma è autentica, solo se l’uguaglianza h(x)= yb mod n è soddisfatta, cosa che avviene solo se la firma è stata ottenuta come y= sigK (x)=xa mod n, cioè solo conoscendo a, e l’esponente a lo conosce solo Alice. Ovviamente questa ragione viene completamente sovvertita se è possibile calcolare la firma senza usare a, e questa cosa è purtroppo fattibile in quanto abbiamo utilizzato una funzione hash, e come ben sappiamo le funzioni hash non sono biunivoche, quindi esistono messaggi diversi che danno luogo allo stesso hash. L’attaccante a questo punto potrebbe fare ciò, osservando una coppia valida (x,y), se è in grado di trovare un messaggio x’≠x tale che h(x’)=h(x), potrebbe concludere che la firma y’ del messaggio x’ è proprio uguale a y che già conosce. Quindi l’attaccante per attaccare lo schema di firma può trovare Collisioni o SecondPreimage su questa funzione di hash, quello che si deve fare allora è prendere una funzione hash che renda infattibile questi tipi di problemi. Un attacco basato sulla chiave soltanto, si effettua trovando un messaggio x tale che il suo hash abbia un determinato valore h(x)=z, dove z= yb mod n, e y è una firma tale da formare una coppia valida con x. Quindi prendo la mia firma y qualsiasi, calcolo z tramite la chiave pubblica, e poi cerco un x tale che h(x)=z, fatto questo avrò trovato la Preimage di un dato valore z. In conclusione gli attacchi possibili su una firma RSA che usa gli hash, sono riconducibili ad attacchi, o meglio soluzioni di problemi, ben noti sulle funzioni hash. A patto quindi di avere una funzione hash Collision Resistant, che non ha cioè vulnerabilità intrinseche, si tratta solo di fare in modo che la soluzioni a questi problemi sia infattibile, ricordando che la loro complessità cresce come 2bit hash/2, basta fare un hash abbastanza lungo da rendere infattibili questi attacchi. Calcolare una firma RSA con funzioni hash induce però l’uso di uno schema di Formattazione, in quanto c’è bisogno di una funzione di mapping F: H�Zn*, tra l’uscita della funzione hash, che è in genere una stringa binaria di 160 - 256 bit, e l’ingresso per RSA, che è un numero che deve essere compreso tra 0…n-1. Lo schema di formattazione, definito chiaramente da questa funzione F è molto critico per la sicurezza, in quanto potrebbe comportare attacchi, come ad esempio i Cube Root Attack (cr problem). Quello che fino ad ora abbiamo chiamato h(x), e che abbiamo usato per calcolare la firma con RSA, è in realtà un numero intero ottenuto da una stringa binaria che contiene h(x). In pratica l’hash vero e proprio che è l’output di SHA-1 ad esempio che è 160 bit, viene formattato in una stringa di lunghezza pari a size(n), pari cioè al numero di bit del modulo n di RSA. Tale formattazione prevede l’aggiunta di padding sulla destra dell’effettivo valore dell’hash, andando a formare una stringa di bit che poi convertita in un intero h di dimensione size(n) costituirà l’ingresso per RSA. La scelta del metodo di inserimento del padding e del modo in cui viene poi convertita la stringa, sono fondamentali per evitare attacchi quali il CRP (Cube Root Problem), e sono specificati negli standard. Supponiamo che il padding venga fatto in questo modo, dato k il numero di bit di n ad esempio 1024, e s il numero di bit dell’hash h(x) (160 se usiamo SHA-1), si inseriscono i 160 bit dell’hash a sx, all’inizio, e poi il padding, k-s bit random, viene inserito di seguito. Questa stringa di k bit verrà convertita in un numero intero u che elevato ad a modulo n costituirà la firma del messaggio x, e questo è quello che farà Alice. Bob, che deve verificare la firma, semplicemente prenderà il messaggio x e ne

Page 61: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 61

calcola l’hash h(x), prende poi la firma, la eleva a b mod n ed otterrà così il numero intero u. Convertendolo in binario otterrà una stringa binaria di k bit, e prendendone i primi s bit andrà a verificare se sono uguali all’hash calcolato. In questo modo, essendo il padding random, colui che verifica non può dire nulla sui k bit ottenuti dalla conversione di u, può solo prendere i primi s bit ed usarli per confrontare l’hash, e questa è la debolezza dovuta ad una mancanza di struttura nel padding. Un possibile attacco a questo schema di padding è il seguente: l’attaccante prende un messaggio m a sua scelta e calcola l’hash di questo messaggio. Prende poi il numero intero v ottenuto dalla conversione di una stringa ottenuta mettendo come primi bit quelli dell’hash di m, e poi tutti zeri nei successivi k-s bit. Supponiamo ora che l’esponente b pubblico sia uguale a 3 (da questo deriva poi Cube Root Problem), quello che l’attaccante fa è calcolare la radice cubica di v che sarà un numero non intero, quindi egli prenderà l’intero più vicino, ad esempio la parte intera superiore che chiameremo r. Questa r è la firma falsificata che l’attaccante spaccerà come firma di Alice del messaggio m, in quanto un qualsiasi verificatore non dovrà fare altro che prendere la firma ed elevarla all’esponente pubblico che è 3. Il numero intero ottenuto, convertito in binario, mi darà i primi k bit che confronterò con l’hash del messaggio, se il confronto ritorna, la firma è autentica. Il confronto tornerà sicuramente in quanto, anche se l’attaccante ha arrotondato il risultato della radice, quando il verificatore trasforma r3 in binario, i k-s bit meno significativi non saranno più nulli come quelli inseriti dall’attaccante, ma appariranno come bit random, cioè il tipo di padding che ci si aspetta da uno schema del genere. In teoria questo tipo di problema si avrebbe con un b qualsiasi, ma in realtà si verifica che l’attacco funziona se è vera la condizione secondo la quale la lunghezza dell’hash non supera 1/b della dimensione di n. Il punto cruciale è quindi inserire una struttura nel padding, che mi consenta di fare delle verifiche sul padding stesso, in più si verifica che è buona norma inserire il padding nei bit più significativi della stringa di bit che verrà poi convertita nell’intero, input di RSA. Parlando di standard, per le firme numeriche esistono lo standard RSA ed il DSS (Digital Signature Standard). L’RSA è quello visto fin’ora, produce firme pari al modulo RSA, 1024 bit ed implica calcoli piuttosto pesanti in quanto bisogna fare esponenziazioni modulo n. Uno schema proposto come più efficiente, a parità di livello di sicurezza è il DSS, che è una variante del ElGamal, quindi la funzione one-way su cui ci si basa è il DL (Discrete Logarithm). Nel DSS si comincia col definire 3 parametri che sono condivisi da tutti (p,q,α) dove p,q sono numeri primi in particolare p deve essere un primo di lunghezza L bit che vedremo è consigliato pari a 1024. Il numero q è un primo di 160 bit che deve essere un fattore di p-1, mentre α è un elemento appartenente a Zp*, cioè un numero intero compreso tra 1….p-1, di ordine q. In Zp*, che è un insieme di 21024 elementi, α di ordine q genererà un sottogruppo composto da 2160 elementi. Essere di ordine q vuol dire che αq=1, ma αi≠1 per ogni i<q. Tale elemento α si ottiene prendendo un qualsiasi elemento g di Zp*, poi si calcola g(p-1)/q mod p e questo lo chiameremo α. Va osservato che costruito così, αq=1 mod p in quanto αq=gp-1 e qualsiasi numero elevato a p-1, da 1 mod p per il teorema di Fermat, ma questo non garantisce che sia di ordine q. Esiste però una proprietà secondo la quale per verificare che un dato elemento α sia di ordine n i un determinato gruppo, è sufficiente verificare che αn=1, e αn/z≠1 per ogni fattore primo z di n. Tale verifica è molto semplice nel caso particolare in cui sia n un numero primo in quanto gli unici fattori di un numero primo sono se stesso ed 1, quindi devo solo verificare che sia α≠1. Dopo aver definito questi parametri pubblici, un utente che voglia costruirsi lo schema di firma deve scegliere la sua chiave privata che non comunicherà mai a nessuno. Sceglie allora a caso un intero a compreso tra 1…q-1 che costituisce la chiave privata, e calcola β=αa mod p che farà parte della chiave pubblica insieme ad α,p,q. Lo schema di firma allora comprende una chiave che è composta dagli elementi K={(p, q, α, a, β ) : β=αa mod p }, e la funzione di firma, dipendente dalla chiave, che applica scegliendo a caso un numero k compreso tra 1…q-1. La firma sarà allora composta dalla coppia di numeri (r, s) con

r = (αk mod p) mod q s = (SHA-1(x) + ar)k–1 mod q

Page 62: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 62

dove q è un numero di 160 bit, quindi la firma finale DSA di un messaggio arbitrario sarà un numero di 320 bit, molto più piccola della firma RSA che risulta di 1024 bit in quanto questa è la dimensione del modulo RSA.

LEZ. 16 – 16/11 (prima parte) - Firme Numeriche DSA e Protocolli di Autenticazione.

Per la generazione dei una firma DSA si parte quindi dalla scelta casuale di un numero k compreso tra 1..q-1, si calcola poi αk mod p, con p numero primo di 1024 bit, mentre q numero primo di 160 bit, si calcola poi s e la coppia (r,s) rappresenta la firma. La verifica invece viene effettuata nel seguente modo: ricevuto il messaggio x, si verifica innanzitutto che 1≤r e s ≤q–1, e poi si calcolano le seguenti quantità

w = s–1 mod q u = w*SHA-1(x) mod q

t = wr mod q v = (αuβt mod p) mod q

Dopodiché si va a verificare, se v=r; notare che in tutto ciò si stanno usando i parametri della chiave pubblica, la firma (r,s), e il messaggio attraverso il suo hash. La verifica in definitiva viene fatta calcolando il numero v e verificando la sua uguaglianza con la parte r della firma, se la risposta è affermativa allora si accetta la firma altrimenti la firma non va bene. In realtà il v che si sta calcolando è

v = (αu+at mod p) mod q = r in quanto u + at = w(SHA-1(x)+ ar) = s-1 k s = k (mod q) e quindi il v risulta avere proprio la stessa struttura di r, per questo accetto la firma se v=r. Per quanto riguarda la sicurezza, si può affermare basilarmente che una siffatta firma è sicura in quanto per imitarla, quindi per produrre la firma, bisognerebbe conoscere la chiave privata, che è celata dentro β. Quindi per trovare la chiave privata bisognerebbe risolvere il problema del logaritmo discreto in Zp*, poiché β=αa mod p, allora si tratta di rendere infattibile questo problema, e con i migliori algoritmi oggi noti questo è infattibile per p di almeno 1024 bit. Per quanto riguarda k invece, anch’esso deve rimanere ignoto, ed esso è celato dentro r, con un operazione mod q cioè un’operazione attuata in un sottogruppo generato da α che è molto più piccolo di Zp*, e in cui non valgono algoritmi efficienti di Index Calcolus, ma soltanto algoritmi la cui migliore efficienza e di tipo Square-root, cioè và con la radice quadrata della numerosità dell’insieme. Ciò vuol dire che la complessità asintotica di qualunque algoritmo oggi pubblicamente noto, applicato sul sottogruppo, ha una complessità che è 2(bit di q)/2=280, complessità che a suo tempo garantiva sicurezza. Questo quindi è il modo in cui lo standard suggerisce di definire i parametri in modo da garantire sicurezza, modo che andrebbe modificato qualora si trovassero algoritmi più efficienti di quelli esistenti ad oggi. Sempre riguardo la sicurezza è importante andare ogni vola a verificare l’esattezza dei parametri che vengono forniti. Verificare cioè che p sia un primo di almeno 1024 bit, q un primo di 160 bit, fattore di p-1, e α un elemento di ordine q di Zp*. Altro aspetto da osservare è che k va usato una sola volta, poi distrutto, dimenticato e generato indipendentemente la volta dopo, in quanto se k diventasse noto, presa l’espressione che calcola s, una sua inversa esplicitata su a darebbe la chiave privata in funzione di r, s, h(x), k, i primi tre sono pubblici, mentre k rappresenta l’unica garanzia del fatto che un attaccante vedendo un messaggio non si possa calcolare a. Se l’attaccante conoscesse due firme DSA valide (x, r, s) e (x’, r, s’) generate con lo stesso k non noto e quindi con lo stesso r, anche se vi sono due differenti s e s’, egli sarebbe in grado di calcolare k a partire dalle firme dei due messaggi tramite la k = (SHA-1(x) - SHA-1(x’))(s - s’)–1 mod q E in questo modo ricavare la chiave privata a di Alice. Del DSA è possibile fare anche la versione a curve ellittiche ECDSA in quanto per come è definito il tutto si parte da un insieme Zp* in cui si è preso un sottogruppo di ordine q, un elemento α che lo genera e poi

Page 63: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 63

definendo l’algoritmo sopra menzionato. Se al posto di Zp* mettiamo un altro gruppo, si può rifare tutto daccapo l’unica cosa è sostituire le operazioni viste, con le operazione del nuovo gruppo. Se come gruppo scelgo allora un gruppo basato su di una curva ellittica, anche qui la firma che si produce è di 320 bit, ciò che sta cambiando è sostanzialmente il gruppo scelto. Il set di parametri pubblici allora consiste nel definire una curva ellittica, che si definisce attraverso un numero primo e i parametri a,b, il numero primo definisce l’insieme su cui vivono i coefficienti e i punti della curva ellittica. L’insieme gruppo invece è formato dai punti della curva ellittica, con l’operazione somma di punti. Detto questo si prende un campo di Galois di ordine n che è un primo oppure qualcosa del tipo 2 elevato ad un numero, per esempio se fosse un primo il campo di Galois di ordine p è Zp*. Quindi fissato il campo di base, si prende la curva ellittica definita dai suoi parametri a,b i cui coefficienti stanno ad esempio dentro Zp*, un punto P di ordine q sulla curva, che è come prendere un elemento α di ordine q. Dopodiché si sceglie un numero a a caso compreso tra 1…q-1 e si calcola Q=aP, che svolge lo stesso ruolo che svolgeva β, cioè trasferire in maniera coperta la chiave segreta e questo perché si ritiene che sia infattibile il problema del logaritmo discreto, una volta dato p,Q, se la curva ha un insieme di punti che è dell’ordine di 2160. La firma anche in questo caso è data dalla coppia r,s, s si calcola esattamente nella stessa formula, mentre r dipende dall’operazione che sta dentro l’insieme, in particolare si prende un k scelto a caso tra 1…q-1, si calcola il punto kP che avrà coordinate cartesiane (u,v) e a questo punto si calcolano

r = u mod q (se n=2m, u è convertito in intero) s = (SHA-1(x) + ar)k–1 mod q

Dopo di ciò la verifica della firma è simile ma è un po’ più efficiente in quanto non c’è nessuna operazione svolta mod p quindi su di un insieme grande:

w = s-1 mod q e1= wSHA-1(x) mod q

e2= wr mod q e1P+ e2Q = (u, v)

trovato allora il punto di coordinate (u, v), si verifica che se la coordinata u mod q = r della firma, allora la firma viene accettata. Va notato che questo calcolo lo può fare chiunque in quanto si basa solo sul messaggio e sulla chiave pubblica. In sostanza tutto ciò risulta un pochino più efficiente in quanto la somma di punti sulla curva ellittica è lievemente più complicata che calcolare prodotti mod q, il vantaggio però è che mentre nell’altro algoritmo di firma ci sono alcuni calcoli che vanno eseguiti su un insieme grande (mod p con p=1024 bit) qui tutti i calcoli sono svolti su insieme dell’ordine di 2160 è quindi è un po’ più efficiente nei calcoli. Per quanto riguarda la sicurezza valgono le stesse identiche considerazioni riguardo l’unicità dell’utilizzo di k, non possono essere nulli r,s e così via. Riguardo le firme allora l’algoritmo base dice che dato un messaggio, la firma serve a calcolare l’autenticatore del messaggio e dell’entità che ha prodotto il messaggio. Con autenticatore si intende un informazione che permette di verificare a) l’identità di chi emette il messaggio, b) che il messaggio non sia stato corrotto, e questo perché la firma dipende dal messaggio, ed inoltre dipende dalla chiave segreta che si suppone nota solo all’entità che emette il messaggio. Esistono poi algoritmi di firma che aggiungono a tutto ciò dei metodi per soddisfare altre proprietà. In particolare le Firme a Conoscenza Zero (Zero Knoledge) sono degli algoritmi di firma che hanno l’obbiettivo di non lasciare in mano a chi verifica, nessuna informazione circa i dati privati di colui che ha firmato. Ciò vuol dire che una volta che Bob verifica la firma di Alice, nel far questo acquisisce da Alice delle informazioni che gli servono per effettuare la verifica della firma. Tali informazioni che Bob ricava dalla firma numerica, sulla chiave segreta di Alice, statisticamente parlando sono identiche a quelle che Bob ricaverebbe se simulasse l’algoritmo di autenticazione da solo, quindi in realtà non ottiene nulla perché tutto quello che ottiene lo avrebbe potuto generare lui stesso. Un esempio classico dell’autenticazione di firma con la proprietà di Zero Knoledge è il Fiat-Shamir, un protocollo basato su crittografia a chiave pubblica articolato secondo il paradigma Commitment

Page 64: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 64

(l’impegno), Challenge (sfida), Answer (risposta). Tale protocollo è stato definito come un protocollo di autenticazione interattivo

Con l’obbiettivo di Bob di autenticare Alice, nel primo passo Alice manda a Bob un messaggio con cui prende un impegno (Commitment), nel secondo passo Bob sfida Alice (Challenge), nel terzo passo Alice risponde e quindi si autentica (Answer). Partiamo dalla premessa che Alice deve preventivamente generare, come tutti gli algoritmi a chiave pubblica, una chiave segreta ed una chiave pubblica, e quest’ultima dovrà essere nota a Bob. Alice prende quindi due numeri primi dello stesso ordine di grandezza p,q e il loro prodotto n, poi sceglie un numero casuale s compreso tra 1..n-1, ne fa il quadrato mod n ottenendo v=s2 mod n, e la coppia (v,n) rappresenta la chiave pubblica, mentre s è la chiave privata. A questo punto Alice sceglie a caso un numero r e calcola x = r2mod n mandandolo a Bob come Commitment, Bob non può conoscere ne ricavare r in quanto dovrebbe fare la radice quadrata, ma memorizza x, e comunque Alice non può cambiare r in quanto ha preso un impegno. Bob sceglie ora un bit a caso e, e Alice deve rispondere con la quantità y = rse mod n in cui compare il numero a caso che ha scelto prima, moltiplicata la chiave segreta elevata ad e. Se la sfida è e=0 Alice deve restituire a Bob r mod n, cioè una delle radici del numero che gli ha dato prima, se invece la sfida è e=1, deve restituire rs mod n. Bob non conoscendo s prende la risposta y ne fa il quadrato y2=r2(s2)e, ma s2 mod n = v è la chiave pubblica e quindi y2=r2ve dove r2mod n= x l’impegno mandato all’inizio. Quindi Bob non fa altro che verificare che la risposta sia y2 = xve mod n, in particolare se Alice ha calcolato correttamente y la verifica torna. Se al posto di Alice c’è Fred (colui che forgia le firme) che vuole spacciarsi per Alice, Fred sceglie a caso un numero r compreso tra 1…n-1, poi calcola x = r2v-bmod n dove b è un bit scelto a caso, e manda x a Bob come impegno. A questo punto Bob manda la sfida e a Fred, e questo ignorandola completamente manda y=r a Bob in quanto non conosce la chiave privata s. Bob per vedere se r è la risposta giusta verifica che il quadrato della risposta che ha ricevuto (y) sia uguale all’impegno (x) preso da Fred, moltiplicato la chiave pubblica elevata alla e: y2=x2ve. A questo punto x2ve calcolato da Bob sarà pari a x2ve=r2ve-b, mentre quello che gli è stato mandato è y2=r2. Accade che Fred riuscirà a spacciarsi per Alice agli occhi di Bob se e solo se la sfida e è uguale al bit a caso b scelto da Fred, e questo può succedere con probabilità ½. Per risolvere questo problema, e quindi abbassare di molto la probabilità che ciò accada, basta aumentare il numero di volte in cui tutto ciò viene fatto, ci saranno k commitment, ed altrettante sfide e risposte, e la firma è accettata solo se tutte le k risposte tornano. E la probabilità che Fred riesca in questo modo a spacciarsi per Alice diminuisce fino a 1/2k, quindi posso far decrescere esponenzialmente questo valore. Questo meccanismo è a Zero Knoledge poiché Bob alla fine ha ricevuto solo una serie di numeri casuali, non può sapere nulla sulla chiave s in quanto è mascherata da numeri casuali. Questo quindi risulta un protocollo di autenticazione interattivo, bisogna vedere se può essere utilizzato per fare una firma numerica a zero knoledge. L’idea base è che Alice genera dei commitment, poi ha bisogno di k bit casuali di sfida, quindi al momento della firma ha bisogno di qualcuno che al posto di Bob la sfidi k volte, come un generatore di bit casuali che però non sia sotto il controllo di Alice. Mi viene incontro in questo caso un’ottima funzione hash crittograficamente robusta che come l’oracolo random, a parità di input mi da sempre lo stesso output, ma tale per cui prima di ottenere l’output io non posso dire nulla su ciò che otterrò. Si procede allora

Page 65: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 65

generando k numeri casuali r1…rk, si calcolano i quadrati xi=ri2 con i=1…k, poi si prende una stringa binaria formata per esempio da m||x1||x2||….||xk, e di questa stringa binaria faccio l’hash. Quindi i bit che ottengo sono funzione dei commitment che devo precalcolare prima di ottenere l’hash in modo che dentro la funzione hash entrino gli impegni presi da Alice. Una volta ottenuto l’hash, una stringa binaria bi di m bit, io ne prenderò solo i k che mi servono, per esempio gli ultimi k e userò questi come sfide per calcolare poi le risposte y1…i che devo dare, yi=risbi , dove bi per i=1…k sono i k bit dell’hash. In questo modo Alice può fare tutto da se e non ha bisogno di interagire con Bob e per permettere a Bob di autenticare il messaggio, bisognerà mandargli, oltre al messaggio stesso, gli impegni e le risposte. Bob che verifica prenderà il messaggio e i k impegni, manderà questa stringa alla funzione hash, prenderà i k bit e farà la classica verifica sulle risposte yi2=xivbi. In questo modo sono riuscito a costruire uno schema di firma Zero Knoledge. Cosa dovrebbe fare allora Fred in questo caso, dovrebbe calcolarsi i numeri xi=r2vi-βi scegliendo prima i βi bit a caso, applicando questo schema poi forma la stringa del messaggio m e degli xi da dare in input all’hash. Una volta calcolato l’hash, prende i k bit, se fortunatamente questi bit coincideranno con le sfide inviate da Bob allora avrà la firma del messaggio m. Ma se anche uno solo di questi bit risulterà diverso, Fred non otterrà la firma, quindi lui a tentativi sceglierà una k-pla di bit per ottenere gli xi, e quindi non può far altro che una ricerca esaustiva a forza bruta. Ciò che sconfigge questa ricerca è la numerosità k, ovviamente se stiamo in tempo reale k può non essere particolarmente elevato, ma sulla firma l’attacco può essere fatto offline quindi devo cautelarmi prendendo k molto più grande, ad esempio 128 bit. Quindi il lato positivo di questa firma è che è zero knoledge , e si può rendere inattaccabile con k di 128 bit. Il lato negativo invece è che l’overhead può essere enorme, k è lungo 128 bit, ognuno degli xi è lungo in termini di bit quanto il modulo n, 1024 bit, quindi ho 128*1024 bit con cui devo calcolare l’hash e che devo poi inviare insieme ad altri 128 bit che sono le risposte, e tutti questi bit non sono comprimibili in quanto random.

LEZ. 17 – 16/11 (seconda parte) - Protocolli di Autenticazione – Key Management.

Le firme numeriche sono utili a costruire meccanismi di non ripudio, in particolare nel caso delle Undeniable Signatures (firme non rinnegabili), si prestano a fare due tipi di verifiche: in primo luogo a verificare che la firma che Alice nega di aver messo è invece effettivamente autentica, la seconda a dimostrare che la firma che Alice non riconosce è effettivamente un falso. Lo schema di Chaum-van Antwerpen, che permette di ottenere questo, è uno schema che parte dalla firma fatta secondo RSA, cioè come y=(h(x))amod p dove p è un numero primo, quindi hash di x convertito in un numero intero, elevato ad a mod p. Al solito bisogna definire un elemento α, un numero intero primo p, un numero β tale che β=αa mod p, dove è scelto a caso a, chiave segreta, compreso tra 1…p-1, α,p,β sono la chiave pubblica e α, di ordine q, è un elemento primitivo di Zp*, fatto questo si calcola la firma y. Il punto cruciale è che una firma tipo RSA può essere diffusa, una volta emessa, al di fuori del controllo di Alice. Si vuole invece definire uno schema dove Alice viene a sapere chi chiede una firma su un proprio documento (il "messaggio" nel seguito). Questo implica che Alice deve essere coinvolta ogni volta che si vuole verificare la firma. Una volta emessa la coppia (x,y), Bob per verificare che la firma y sia di Alice, deve sfidarla (coinvolgendola, Alice sa che Bob ha il suo documento e vuole una verifica della firma) quindi sceglie a caso una coppia di numeri interi (e1,e2) e calcola c=ye1 βe2 mod p (la sfida) e la invia ad Alice. Quest’ultima deve rispondere calcolando d=cz mod p, con z=a–1 mod q e la invia a Bob, che effettua la verifica controllando che sia verificata l’uguaglianza d=(h(x))e1αe2 mod p. Nell'ambito di questa logica però, sorgono due problemi. Se la verifica fallisce, Bob potrebbe sospettare (che malfidato!) che Alice l'abbia fatto di proposito per ripudiare una firma valida (infatti l'unico modo per Bob di verificare se la firma è valida è chiedere la cooperazione di Alice). D'altra parte, se la firma è

Page 66: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 66

effettivamente non valida, come può la povera Alice provare che non sta imbrogliando e che effettivamente la sfida fallisce perché è la firma che non è valida e non lei che è una bugiarda? Il Disavowal Protocol serve a superare questi due problemi. Per capire come funziona il protocollo, distinguiamo due casi: 1. Alice è onesta e giustamente nega di aver mai firmato il messaggio (la firma e' falsa e non valida).

Bob sfida Alice, sceglie a caso una coppia di numeri interi (e1,e2) e calcola c=ye1 βe2 mod p e la invia ad Alice. Alice fornisce la risposta d=cz mod p, con z=a–1 mod q (calcolata correttamente, in base alla chiave privata a; Alice e' onesta!). Bob verifica che d≠(h(x))e1αe2 mod p, non può dire che la firma è valida (se fosse uguale si), allora sfida ancora Alice, risceglie a caso una coppia di numeri interi (f1,f2) e calcola C=yf1 βf2 mod p e la invia ad Alice. Quest’ultima fornisce la nuova risposta D=Cz mod p, con z=a–1 mod q (di nuovo calcolata correttamente, in base alla chiave privata a; Alice e' onesta!). Bob verifica che D≠(h(x))f1αf2 mod p e (di nuovo la firma non è valida), sospettoso, verifica anche che (dα-e2)f1=(Dα-f2) e1 (Consistency Check) e si tranquillizza. Se d e D sono stati calcolati correttamente con la giusta chiave segreta infatti, il controllo di coerenza ha successo (vale l'uguaglianza) e Alice ha così dimostrato che la firma è effettivamente un FALSO. 2. Alice imbroglia e vuol negare di aver firmato un messaggio che in effetti aveva (correttamente) firmato.

Bob sfida Alice, sceglie a caso una coppia di numeri interi (e1,e2) e calcola c=ye1 βe2 mod p e la invia ad Alice. Alice fornisce una risposta d fasulla (quindi non calcolata con la sua chiave privata a altrimenti verrebbe soddisfatta l’uguaglianza d=(h(x))e1αe2 mod p ), per mostrare che la firma non e' valida (che spudorata!). Bob sfida ancora Alice, risceglie a caso una coppia di numeri interi (f1,f2) e calcola c=yf1 βf2 mod p e la invia, e Alice di nuovo fornisce una risposta D fasulla (senza vergogna!). Bob verifica che (dα-e2)f1≠(Dα-f2) e1, mostrando così che in effetti la firma y era proprio corretta (infatti, solo se viene = la firma è un FALSO, come nel caso 1; ma per far tornare l'= occorre calcolare d e D correttamente con la stessa chiave privata a usata per la firma y, ma se quella fasullona di Alice lo avesse fatto nelle due precedenti sfide, avrebbe già ammesso che la firma è valida). L'analisi dei casi 1 e 2 si fonda su queste tre proprietà, dimostrare nello Stinson.

P1 - Se y≠(h(x))a mod p, allora Bob accetta y come firma valida del messaggio x con probabilità 1/q.

P2 - Se y≠(h(x))a mod p e Bob e Alice seguono il disavowal protocol, risulterà che (dα-e2)f1=(Dα-f2) e1.

P3 - Supposto y=(h(x))a mod p con Bob che segue il disavowal protocol. Se d≠(h(x))e1αe2 mod p, e D≠(h(x))f1αf2 mod p, allora la probabilità che (dα-e2)f1≠(Dα-f2) e1 è 1-1/q.

Notate che nella proprietà P2 si assume che Alice segua il protocollo (e' onesta), mentre la proprietà P3 vale qualunque cosa faccia Alice.

Cominciamo a vedere ora le problematiche connesse con i protocolli che fanno uso di questi meccanismi crittografici. In particolare i protocolli crittografici sono utilizzati per condividere chiavi segrete o distribuire chiavi pubbliche. Ricordando tutti i meccanismi crittografici già visti, notiamo che questi partono tutti dal presupposto che le due parti in comunicazione condividono la chiave segreta, oppure uno è in possesso della chiave autentica dell’altro. Definiamo ora come si arriva a questo presupposto. Innanzitutto bisogna definire se il contesto è quello della crittografia a chiave pubblica oppure quello della crittografia a chiave simmetrica. In entrambi i casi la distribuzione delle chiavi è attuata sia dalle parti in gioco, Alice e Bob, sia anche poggiandosi su una terza parte fidata, il server che distribuisce le chiavi, che si dividono in chiave Master e chiavi di Sessione. Generalmente si stabilisce che due o più entità che devono instaurare canali sicuri tra loro, ad esempio attuando funzioni di cifratura e/o di autenticazione di

Page 67: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 67

messaggi, precondividono un qualche tipo di segreto, e ciò può essere ottenuto anche con mezzi non telematici, magari offline. Queste chiavi di lungo termine, precondivise dalle parti A e B, prendono il nome di chiavi Master, in quanto a partire da esse io desumo le chiavi derivate che si utilizzerò in ogni specifica interazione tra A e B che devono condividere una comunicazione sicura. Quindi si fa lo sforzo di distribuire le chiavi tra A e B, fatto questo, ogniqualvolta dovranno scambiarsi informazioni, A e B per prima cosa si autenticheranno utilizzando la Master Key, poi dopo, sempre usando la Master Key, genereranno la chiave di sessione, cioè una chiave derivata che potrà essere utilizzata per cifrare oppure per autenticare messaggi all’interno della sessione. Le chiavi, che rappresentano l’elemento base per realizzare le primitive crittografiche, presentano tutta una serie di problematiche connesse, che sotto molti aspetti richiamano quelle delle chiavi del mondo fisico. Anzitutto le chiavi vanno generate, con i relativi problemi di generazione, vanno poi distribuite in quanto hanno senso se sono condivise tra le parti che devono comunicare utilizzando meccanismi crittografici che fanno uso di quelle chiavi. C’è poi il problema di verifica delle chiavi, supponiamo di aver distribuito una certa chiave tra più parti, le varie parti devono poter verificare che la chiave corrisponde ai requisiti precisati. Altri problemi connessi con le chiavi riguardano il fatto che le chiavi, sia quelle di sessione sia a maggior ragione quelle Master, vanno ovviamente memorizzate, e questo è fonte di un numero enorme di problemi. In un progetto di un sistema reale poi bisogna pensare alle chiavi di scorta, pensare cioè a come fare per replicare, e mantenere in modo sicuro, copie della chiave. Altri aspetti riguardano la distruzione delle chiavi, che devono avere vita finita, non si possono tenere in eterno in quanto si logorano. Più si usa una chiave, più si mettono in giro informazione prodotte con quella chiave, e quindi più si offrono possibilità ad un attaccante di accumulare informazioni che in un modo o nell’altro potrebbero portarlo ad individuare la chiave. Usare chiavi di sessione indipendenti, rende appunto indipendente, da sessione a sessione, la sicurezza, aspetto, questo, molto utile. Questo paradigma delle chiavi Master e delle chiavi di Sessione comporta che, le chiavi Master vengono distribuite con procedure molto complesse che però, essendo fatte molto di rado, assumiamo fattibili. Per le chiavi di sessione, che saranno usate molto più spesso, bisognerà creare dei meccanismi che permettano alle entità in gioco di autenticarsi e concordare chiavi da usare nella sessione. Questo è lo scopo per cui servono i protocolli crittografici. Nel nostro contesto allora saranno presenti due entità A e B che devono arrivare a condividere una o più chiavi di sessione, che permetteranno di abilitare la condivisione di canali sicuri. In questo contesto la Fiducia rappresenta una base fondamentale per l’interazione tra le entità, e quindi anche per i protocolli. Rappresentano incentivi ad un comportamento fidato l’Etica, la Reputazione, la Legge, la Minaccia fisica, il MAD (Mutually Assured Destruction, distruzione mutuamente assicurata) nessuno si spinge troppo oltre se c’è la consapevolezza di essere comunque tutti distrutti (cold war term). Detto questo, un protocollo crittografico ha una serie di aspetti molto interessanti, in particolare anzitutto può essere collocato a diversi livelli dell’architettura di rete, quindi vuol dire che sotto di esso c’è tutto un altro sistema di protocolli che si occupa della comunicazione e del trasferimento dei messaggi, e che rappresenta un presupposto per il protocollo crittografico. Generalmente allora i protocolli crittografici assumono che sia possibile consegnare messaggi integri al destinatario, anche se non per forza assumono che la consegna sia certa. Dopodiché il protocollo, oltre a eseguire algoritmi crittografici che servono per esempio all’autenticazione, deve far fronte ad una serie di questioni quali:

- l’Identità: ogni messaggio di un protocollo deve portare l’informazione sufficiente per identificare a quale protocollo appartiene e a quale versione del protocollo, e anche che tipo di messaggio è nell’ambito di quel protocollo.

- l’Encoding and parsing: un messaggio è in ultima analisi una stringa binaria, per affermare che un certo numero di bit è corretto o meno devo saper fare in maniera univoca il parsing del messaggio. Cioè riuscendo a raggruppare i bit secondo un certo schema (parsing), in modo da identificare e interpretare (encoding) la struttura nota e vincolata di quel dato pacchetto protocollare.

Page 68: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 68

- l’Error handling: gestione degli errori; i protocolli forniscono sia al sistema locale, sia al sistema remoto, dei feedback, messaggi di notifica di errore utili a gestire le eccezioni.

- Il Distinguish: bisogna stare attenti a distinguere i messaggi replicati da un attaccante dai messaggi re inviati dal protocollo (Replay and Retries).

Retries and Replay.

Per quanto riguarda poi l’affidabilità dei messaggi, bisogna poi definire cosa faccio quando ricevo un messaggio. I protocolli crittografici quasi sempre sono protocolli del tipo Request-Replay, con una richiesta e una risposta che può a sua volta richiedere qualcosa. In questo scenario quindi, se arriva un messaggio inaspettato, la cosa migliore è non fare nulla, in quanto se sotto c’è un’infrastruttura che garantisce affidabilità e si tratta di un errore, riuscirò a risolvere questo problema. Se non era un errore ma un attacco, meglio ancora, in quanto non l’ho considerato. Se invece ricevo un messaggio perfettamente identico a quello appena ricevuto, il miglior comportamento rimane quello di rimandare esattamente la stessa risposta mandata precedentemente. Se invece ricevo lo stesso messaggio che ho appena ricevuto, ma alcuni dei campi hanno contenuti diversi, tipicamente l’atteggiamento migliore suggerisce di ignorare tale messaggio. Lo stesso comportamento viene adoperato se ricevo un vecchio messaggio, vecchio nel senso che non è l’ultimo ricevuto ma ancora più indietro.

LEZ. 18 – 22/11 - Protocolli crittografici – Diffie-Hellman e sue varianti autenticate.

Continuiamo a parlare di protocolli crittografici. Un protocollo è un insieme di procedure delle quali specifichiamo le semantiche dei messaggi, cioè quali azioni rispondono alla ricezione o emissione dei messaggi, e la relativa temporizzazione. In questo caso, crittografico vuole intendere un protocollo volto essenzialmente alla condivisione di segreti, a far condividere, a due o più entità, una chiave di sessione, con lo scopo di abilitare alcuni meccanismi di creazione di canali sicuri, per esempio cifratura e autenticazione. L’obbiettivo che ci si pone allora nell’esecuzione di un protocollo crittografico è quello di arrivare in fondo a garantire due caratteristiche principali della chiave di sessione: l’esclusività, e la freschezza. Bisogna arrivare a dire in pratica che, la chiave di sessione che verrà concordata tra A e B sarà nota a essi soltanto, e che la chiave verrà generata all’occasione, cioè generata, in quella esecuzione del protocollo, in maniera indipendente da ogni altra precedente generazione. In pratica si parlerà più in generale di protocolli di autenticazione e scambio chiavi, poiché le due funzioni sono strettamente legate in quanto per poter condividere una chiave con B, A deve essere sicuro che sia effettivamente B l’entità con cui sta dialogando. In generale si parla di Key Establishment Protocol, ma più specificatamente si distinguono in:

- Protocolli di Trasporto delle chiavi (Key Transport Protocol), quando una delle parti stabilisce la chiave di sessione e la trasferisce verso l’altra parte;

- Protocolli con cui si concordano le chiavi (Key Agreement Protocol), quando tutte e due le parti forniscono informazioni che servono a calcolare la chiave di sessione.

Quando si progettano o si analizzano protocolli crittografici, ovvero la parte crittografica di un protocollo per canali sicuri, si fanno generalmente delle assunzioni per garantirne la robustezza in termini di sicurezza. Il modello entro il quale ci si mette ha questi presupposti:

- a) si fa un protocollo per far autenticare vicendevolmente e far condividere una chiave a due entità A e B;

- b) A e B comunicano attraverso una rete che si suppone insicura, in cui cioè un avversario, colui che cerca di trarre dei vantaggi illeciti e/o far fallire un protocollo, è in grado di intercettare qualunque messaggio del protocollo;

Page 69: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 69

- c) l’avversario è in grado di alterare in un modo qualsiasi il flusso dei messaggi del protocollo, impedendo a B di ricevere un messaggio, di far ricevere a B un messaggio fabbricato, di cambiare l’ordine dei messaggi;

- d) l’avversario potrebbe essere un esterno, un outsider, oppure un insider, in un esempio di commercio elettronico è necessario quindi inserire meccanismi di non ripudio tra le parti in gioco;

- e) in un contesto di reti virtualmente private sicure (SVPN) basata su IPSEC, quindi una serie di router di reti locali aziendali che si interconnettono creando canali sicuri, normalmente si assume che i router siano “onesti”. Tradotto in termini più tecnici si intende che conto sul fatto che quella macchina non sia stata attaccata e non sia in mano all’avversario, in quanto si assume che i router siano ben protetti;

- f) bisogna assumere che l’avversario sia in grado di venire a sapere qual è la chiave segreta di sessione concordata in tutte le sessioni sufficientemente vecchie.

I meccanismi visti fino ad oggi rappresentano quindi i mattoncini che utilizzeremo per mettere su protocolli, in particolare: quelli che permettono di cifrare; soprattutto quelli che permettono di verificare l’integrità dei dati, intesa sia come messaggi non alterati, sia come autenticità della sorgente; eventualmente i meccanismi di non ripudio. Per quanto riguarda la freschezza dei messaggi, uno degli elementi cruciali è garantire in un certo senso l’unicità di ogni esecuzione del protocollo. Garantire cioè che l’entità con cui si sta dialogando sia “viva”, cioè stia dialogando in quel momento, e che i messaggi non siano invece repliche di vecchi messaggi catturati dall’avversario e mandati in giro successivamente. Ci sono allora varie modalità per garantire “freschezza”, una possibile è mettere Timestamps sui messaggi. Ricordiamo a questo proposito che i messaggi sono protetti in integrità per esempio attraverso dei MAC, il che significa che qualunque cosa che metto nel massaggio non potrà essere alterata, e se lo fosse, chi lo riceve è in grado di accorgersene ma non di correggere. I Timestamps sono utilizzati per esempio in protocolli di Key Establishment, più propriamente Key Transport, tipo Kerberos, e un presupposto scomodo dei timestamps è che le macchine che dialogano nel protocollo debbono essere sincronizzate. Un altro modo di ottenere freschezza sono i Contatori, oppure attraverso l’uso dei Nonce, che abbiamo già incontrato, delle sequenze ottenute in qualche modo o come generazione casuale, o attraverso proprio l’uso di contatori oppure timestamps, l’importante del Nonce è che comunque ottenuto, è possibile affermare che con probabilità estremamente elevata, quel valore viene usato una volta sola. Una lista più o meno esaustiva di possibili attacchi è la seguente:

Innanzitutto ci sono gli attacchi passivi (Eavesdropping), l’attaccante ascolta e acquisisce informazioni che userà per qualche suo scopo, ad esempio PasswordGuessing, attacchi a forza bruta di tipo offline sulle

Page 70: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 70

password. Molto più importanti di questi però sono gli attacchi attivi, in cui cioè l’avversario interviene a modificare qualcosa nel flusso o a spacciarsi per qualcuna delle parti. Vediamo ora il primo esempio di protocollo di autenticazione molto famoso, il Diffie–Hellman Key Exchange. Innanzitutto questo protocollo rappresenta l’idea di base di tutti gli effettivi protocolli di autenticazione contenuti in tutte le maggiori suite crittografiche istallate sui nostri calcolatori. La cosa più interessante è che i due partecipanti A e B arrivano a condividere un segreto senza precondividere alcun segreto prima, e lo fanno in modo da essere robusti ad attacchi passivi. Soccombe invece tranquillamente ad attacchi attivi in quanto non è autenticato. Il contesto è lo stesso di ElGamal, si prende quindi un primo p grande, almeno 1024 bit, un primo q che sia un fattore di p-1, e poi un elemento α di ordine q del gruppo Zp*, cioè dell’insieme delle classi residue modulo p, cioè da 1…p-1. Deve essere q di 256 bit per esempio, se la soglia di sicurezza rispetto ad attacchi a forza bruta è 2128. I parametri (p, q, α) devono essere pubblici, e tutto si basa sul problema del Logaritmo Discreto (DL) ambientato nel sottogruppo di ordine q generato da α. In particolare facendo riferimento allo schema successivo

A e B non condividono nulla prima, A sceglie un numero a caso a compreso tra 1…q, e poi calcola la quantità yA = αa mod p. Va notato che qualunque potenza di α vive dentro questo sottogruppo di ordine q, cioè genera un numero che sta dentro quel sottogruppo. A questo punto A manda a B questo numero yA, un attaccante che ascoltasse yA, conoscendo α,p in quanto pubblici non può risalire ad a, il numero segreto scelto a caso da A, perché far questo significherebbe risolvere il problema del logaritmo discreto dentro il sottogruppo di ordine q generato da α, e se q è abbastanza grande, questo è infattibile in quanto soggetto ad una complessità che è un O(2128) con q di 256 bit. Quindi mandare in giro yA in un canale insicuro non compromette la sicurezza in quanto, la quantità che non si deve venire a sapere, questo a, non si può ricostruire a partire da yA. B fa esattamente la stessa cosa, sceglie un valore b a caso compreso tra 1…q, calcola yB e lo manda ad A. A questo punto entrambe le parti fanno la stessa cosa, in particolare A prende yB ricevuto, lo eleva all’esponente segreto a che ha generato prima e non ha mai trasmesso a nessuno, ottenendo k =yBa mod p = αab mod p , allo stesso modo B otterà k =yAb mod p =αab mod p. A e B sono arrivate così a condividere un numero k che solo loro conoscono, perché chiunque abbia ascoltato questo scambio di messaggi, non può ricostruire a,b per le proprietà del DL, e quindi non può calcolare quel numero k. Brevemente allora la chiave condivisa tra A e B è questo k, che tradotto in stringa binaria è lungo tanto quanto p, un numero scelto con criteri tali da rendere infattibile il problema del DL, e quindi allo stato dell’arte di oggi è lungo 1024 bit. Quindi si ottiene una chiave k che è rappresentabile con 1024 bit, che se usati per generare delle chiavi di sessione a 128 bit, sono decisamente eccessivi. Allora un modo pratico utilizzato per tirar fuori una chiave da k è fare operazioni di hash, cioè usare questo dato condiviso più eventuali altri dati scambiati nel corso del protocollo, dentro un hash, che mi fornirà i bit che utilizzerò per la chiave. Questo ha di buono anche che fare l’hash di questa quantità, distrugge il nesso tra la chiave che

Page 71: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 71

effettivamente si userà, il risultato dell’hash, e la struttura matematica che ha portato a definire questo k, e cioè l’aritmetica mod p. Altro dettaglio è che la sicurezza passiva, rispetto cioè ad intercettazioni, di questo protocollo, regge sul fatto che il DL sia infattibile, e quindi sia A che B debbono cautelarsi sul fatto che i parametri utilizzati, in particolare (p,q,α), rispettino i giusti criteri, quelli cioè elencati sopra. Se non si verificano questi criteri, un possibile attacco è quello dello Small Subgroup, cioè indurre i due ad utilizzare un α che non è di ordine q, ma di ordine molto più piccolo, in modo da rendere fattibile la ricerca esaustiva del Logaritmo Discreto. Tra gli attacchi attivi, il più devastante è quello cosiddetto Man in the Middle, secondo il quale dati Alice e Bob che si scambiano yA e yB, non c’è nulla che autentichi la provenienza e l’integrità di questi due numeri che entrambi ricevono. L’avversario allora, ponendosi in mezzo, preleva l’ yA mandato da Alice, e lo sostituisce con un yA’ , calcolato secondo lo stesso protocollo, spacciandosi per Alice, Bob a questo punto risponde alla presunta Alice mandando il suo yB, e quindi i due possono concordare una chiave segreta. Il risultato è che sia Alice che Bob stanno condividendo, separatamente, una chiave segreta con l’attaccante, quindi tutto ciò che Alice e Bob si scambieranno successivamente nella sessione potrà essere letto, e loro non sapranno mai che tra di loro c’è una terza entità. Tutto questo dipende dal fatto che il DH è l’idea centrale per arrivare a condividere un segreto, ma manca di un pezzo fondamentale, non è autenticato, né Alice né Bob sanno con chi stanno parlando. Vediamo allora come mettere su un protocollo di comunicazione esaminando via via diverse versioni attaccabili, e cercando di rimuovere gli attacchi. Nel seguito la notazione cambia leggermente, laddove c’era α, ci sarà g, ma l’ambientazione è quella del Diffie-Hellman, con l’aggiunta dell’autenticazione, il che significa che Alice e Bob in realtà precondividono un qualche segreto. Quello che si farà è generare, per ogni singola sessione, chiavi ad hoc per quella singola sessione, che verranno usate e poi gettate via. Per generarle partirò dalla precondivisione di una Master Key, di un segreto, chiave che verrà utilizzata esclusivamente nell’esecuzione del protocollo di autenticazione (pochi messaggi), e poi non più utilizzata, nella sessione invece si utilizzeranno chiavi concordate per l’occasione. Questo oltre al fatto di esporre la chiave di lunga termine al minimo numero possibile di attacchi critto analitici, ha anche il vantaggio di disaccoppiare la sicurezza della sessione dalla sicurezza del protocollo di autenticazione. Ci sono due possibilità allora di precondividere un segreto, o si condivide una chiave segreta, una vera e propria chiave comune e allora quello che manca, l’autenticazione, si può ottenere attraverso un MAC, oppure si possono usare schemi di firma, ma per usare tali schemi Alice e Bob devono precondividere le rispettive chiavi pubbliche autentiche. In pratica ciò si ottiene in questo modo: invece di avere le chiavi pubbliche di tutti i possibili Bob, Alice ha un insieme più ristretto di chiavi pubbliche, e Bob, quando si presenta, non solo manda ad Alice il suo messaggio firmato, ma manderà anche un certificato che associa la sua identità alla sua chiave pubblica, cioè è lui stesso a darmi la sua chiave pubblica. Per dimostrare che la chiave pubblica è autentica, Bob invierà un documento che si chiama Certificato, a sua volta firmato utilizzando la chiave pubblica/privata di una terza parte, che si chiama Autorità di Certificazione. A questo punto Alice dovrà avere la chiave pubblica autentica non di Bob, ma dell’Autorità di Certificazione. Alice riceverà allora il messaggio firmato, ed il certificato che contiene la firma della CA (Certification Authority), e quindi prima verificherà questa firma tramite la chiave pubblica della CA, quindi verificherà che il certificato mandato da Bob sia effettivamente autentico, e per far questo ha bisogno di una sola chiave pubblica autentica. Quindi il dato iniziale che deve essere noto prima di iniziare il protocollo, è la chiave pubblica autentica della CA di Bob. Nel certificato allora ci sarà scritto Bob e chiave pubblica di Bob, più tante altre cose, una volta verificato che il certificato è autentico, Alice legge. Allora quell’entità che si chiama Bob ha questa chiave pubblica garantita da CA, quindi Alice userà questa chiave pubblica per verificare la firma di Bob, e verificare quindi se il suo messaggio è autentico. Dal momento in cui Alice ha verificato il certificato, possiede automaticamente la chiave pubblica autentica di Bob, e questa fiducia si basa sul fatto di sapere che la CA sia autentica e che la CA sia seria, quindi abbia già verificato l’autenticità di Bob. Ciò che ho guadagnato in questo modo, è che se si presentasse Charlie o qualunque altro al posto di Bob, questi dovranno mandare ad Alice il loro certificato con annessa chiave pubblica, e se tutti questi fanno capo ad un'unica CA, disponendo della sola chiave pubblica della CA, Alice potrà autenticare tante chiavi pubbliche

Page 72: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 72

di tanti diversi utenti, ognuno dei quali mostrerà ad Alice il suo certificato. La collezione di chiavi che deve avere Alice cresce man mano che cresce il numero delle CA. Detto ciò nel seguito supporremo che i messaggi scambiati tra Alice e Bob possono essere autenticati. L’autenticazione può avvenire o su MAC basati sulla chiave Master precondivisa (crittografia simmetrica), oppure su Firme Numeriche basate sulle chiavi segrete disponibili ad Alice e Bob, chiavi controllate grazie al fatto che si suppone che Alice conosca la chiave pubblica autentica di Bob e viceversa. Computazionalmente è più efficiente usare il MAC, anche perché il contesto a chiave pubblica ha una serie di vantaggi ma si presuppone l’esistenza di una PKI (Public Key Infrastructure), di un CA, quindi dipende molto dal contesto. Nel seguito quindi quando c’è scritto AUTH(), il contenuto dell’argomento di questa funzione viene autenticato, come dipende dal contesto, MAC o Firma Numerica. Il primo tentativo per aggiungere autenticazione al DH è il seguente. Preso il DH così com’è, ci si aggiunge dopo l’autenticazione

Prendo allora un x a caso, calcolo X = gx mod p, e lo mando a B, che a sua volta genera un y a caso,

calcola un Y = gy mod p, e valuta k =Xy mod p = gxy mod p, mandando poi Y ad A, la quale a sua volta valuterà k =Yx mod p = gyx mod p, e fin qui è il DH.

Il secondo passo è il seguente

Entrambi A e B calcolano l’autenticatore di k e se lo scambiano. Questa è una prova di autenticazione in quanto poiché questo protocollo è sicuro rispetto ad attacchi passivi, le due uniche entità che sono in grado di conoscere k sono quelle che si sono appena scambiate X,Y, quindi una terza parte che avesse intercettato la coppia X,Y, non sarebbe in grado di calcolare k. A quindi sta dando una prova che conosce il k comune, ma non manda direttamente il k, bensì un calcolo fatto su di esso, un autenticatore, per esempio la firma su k. Bob a questo punto, conoscendo k ne verifica la firma, in quanto conosce la chiave pubblica autentica di Alice, va notato che nel solito paradigma in cui A e B si scambiano la coppia (messaggio, autenticatore), qui A e B si stanno scambiando solo l’autenticatore, in quanto si presuppone che Bob, essendo quello autentico, già conosca il messaggio k, quindi deve soltanto verificare l’autenticatore. Se Alice è stata in grado di produrre questo autenticatore, la sua identità è garantita dal fatto che la chiave privata per fare quell’autenticatore ce l’ha solo lei. Bob sa che chi gli ha mandato X, e ha fatto la successiva autenticazione, è proprio Alice, in quanto gli sta dimostrando di conoscere k, cosa che poteva accadere solo se era a conoscenza dell’esponente segreto x. Ci sono però molte obbiezioni a questo protocollo che in realtà non funziona, alcune di efficienza, e altre proprio di sicurezza. Intanto i parametri del protocollo (p, q, g) sono delle costanti, mentre invece in ogni sano protocollo è meglio negoziarle, perché non è detto che ci sia compatibilità tra i due sistemi, non è detto che i parametri che vanno bene ad Alice vadano bene a Bob, in quanto questo potrebbe avere politiche di sicurezza più stringenti. Un altro aspetto di efficienza è che ci sono voluti 4 messaggi per fare questo, quando invece come vedremo adesso ne bastano 3. Altri due aspetti proprio di sicurezza sono i seguenti: è vero che non stiamo trasmettendo k in chiaro, però stiamo mandando in giro una quantità direttamente legata a questo valore, che poi pretenderemmo di usare come chiave segreta, e ciò non va bene. Stiamo comunque dando in qualche modo informazione, sia pure indiretta, sulla chiave di sessione. L’altro aspetto molto importante per la sicurezza, è che gli ultimi due messaggi sono troppo simili tra loro, se stessimo usando autenticazione basata su chiave simmetrica (MAC), addirittura sarebbe lo stesso.

Page 73: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 73

Bisogna quindi procedere in questo modo, in particolare l’autenticazione d’ora in poi segue il principio secondo il quale un autenticatore apposto ad un messaggio, che sia Firma o che sia MAC, autentica tutti i campi di quel messaggio, e tutti i messaggi precedenti. Calcolare un autenticatore, negli algoritmi di pratico impiego, consiste nel prendere l’oggetto da autenticare, farne l’hash e poi fare un calcolo, la cui complessità non dipenderà dall’oggetto da autenticare in quanto si farà prima un hash. Quindi l’autenticazione di più messaggi precedenti altera molto poco la complessità di tutto l’algoritmo di autenticazione. Ciò che si fa allora è la seguente cosa

A sceglie (p, q, g), genera x calcola X=gx mod p e manda tutto a B, compresi (p, q, g) che questa volta vanno negoziati, non sono fissi, poi manda X e autentica il tutto. Bob prima di tutto verifica l’autenticità del messaggio, poi verifica (p, q, g), cioè verifica che sia p primo e di una lunghezza a lui soddisfacente, che q sia un primo, fattore di p-1, e che g sia un elemento di ordine q (cioè g≠1, gq=1). Verifica poi che X sia un numero di ordine q, e a sua volta genera il suo esponente segreto, e calcola Y=gy mod p e si calcola la chiave k=Xy. A questo punto manderà ad Alice Y, autenticando questo e tutto il messaggio precedentemente ricevuto, dando una prova che B è B, in quanto ha messo un’autenticazione che solo B poteva mettere. Inoltre sta mandando un messaggio “fresco” che non può essere per esempio una copia di un vecchio messaggio, in quanto AUTHB, dovendo autenticare anche il messaggio precedente, troverà sicuramente un X diverso (da quello che c’era nel messaggio precedente copiato), cambiato proprio da Alice scegliendo a caso un altro x. In generale è fondamentale quindi inserire dei Nonce (x,y) e autenticarli in maniera tale da garantire la freschezza dei messaggi a tutti e due. Vediamo ora i difetti di questo protocollo. In effetti i parametri (p, q, g) non sono effettivamente negoziati, è Alice che li impone a Bob, che potrebbe abortire il protocollo in quanto non soddisfano i suoi requisiti. È vero poi che Bob non riesce ad essere sicuro della freschezza dei messaggi di Alice, qualcuno potrebbe spacciarsi per lei copiando un precedente messaggio, e Bob sarebbe convinto di aver chiuso a buon fine il protocollo e di condividere, con la supposta Alice, una chiave segreta. Per correggere questi due difetti bisogna ricorrere a tre messaggi, in particolareil primo è senza autenticatore

Page 74: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 74

ed s definisce qual è la minima dimensione di p accettabile per A, mentre NA è un numero random, un Nonce, che servirà come sfida per garantire la freschezza della risposta. A questo punto Bob conferma o aumenta il valore in bit di p, genera y e Y=gy (che fungerà anche da Nonce), e manda tutto ad Alice, autenticando anche il messaggio precedente, eliminando in questo caso il problema di possibili replay. Alice verificherà l’autenticatore, esegue un controllo sui parametri (p,q,g) e Y, genera x, X=gx, calcola la chiave k=Yx, e manda a Bob X e il suo autenticatore che autenticherà anche tutti i messaggi precedenti. Occorre fare però delle piccole correzioni. Non conviene tenersi la chiave così, in quanto troppo direttamente legata ai parametri pubblici del DH, e quindi conviene ricavare la chiave con operazioni di hash, ottenendo quindi una stringa dipendente da k e che tutti e due sono in grado di calcolare. Un’altra piccola correzione riguarda il fatto che Alice chiede a Bob di trovare un numero primo p di s bit, fatto questo che aprirebbe la strada ad attacchi di tipo Denial of Service, in quanto si potrebbe chiedere ad un server di generare p primo di dimensioni assurde, e questo causerebbe un out of service, va messo quindi un controllo su questo. In particolare una soluzione possibile è fare in modo che sia Alice che Bob abbiano un valore minimo di p richiesto ed un valore massimo che sono disposti ad accettare; il minimo è dettato da condizioni di sicurezza, mentre il massimo da condizioni di complessità computazionale, dove il massimo è indicato da F volte il valore preferito s. Quindi Alice ha il suo minimo sA = min p size, poi genera il Nonce NA (random)e li manda a Bob che ha il suo di minimo sB = min p size, quindi fa s = max(sA,sB) e poi lo verifica, cioè vede se è al di sotto della soglia computazionale che si è posto. Se la verifica va a buon fine, Bob sceglie (p, q, g) con s-1≤log2p<s, genera poi y e Y=gy e manda (p, q, g), Y, AUTHB ad Alice. Per prima cosa allora Alice verifica l’autenticità del messaggio che riceve, poi passa a verificare la terna (p,q,g), cioè p deve essere di almeno il numero di bit che lei ha richiesto, e non deve superare il valore massimo riferito al valore di complessità computazionale che ha deciso. Segue poi con il verificare gli altri due, genera poi x and X=gx e rimanda indietro X, AUTHA calcolando infine il numero condiviso k e da quello la chiave concordata, tramite la funzione hash. Lo schema definitivo è il seguente:

Page 75: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 75

Questo risulta essere un protocollo che autentica Alice a Bob e viceversa, presupponendo ovviamente che condividono un segreto di lungo termine, o almeno la chiave autentica l’uno dell’altro, che sventa attacchi di Replay per esempio, ma non è detto che sia al sicuro da ogni possibile attacco. In più non è detto che sia facile passare da un semplice modello a flusso come quello qui rappresentato, all’implementazione vera e propria del protocollo.

LEZ. 19 – 23/11 – Forward Secrecy in DH - Autenticazione.

Il concetto che andiamo ad analizzare ora è quello della Sicurezza in avanti Forward Secrecy, in particolare vediamo perché si vuole concordare una chiave di sessione diversa dalla chiave di lungo termine rinnovata poi ad ogni sessione. Il motivo principale è senza dubbio quello di rendere indipendente una sessione dall’altra, per cui la compromissione della chiave di una sessione non comprometterà assolutamente le altre sessioni, e rendere poi indipendente la chiave di sessione dalla chiave di lungo termine. Indipendente nel senso che anche conoscendo la chiave di lungo termine, non sarà fattibile conoscere la chiave di una qualunque delle sessioni già svolte. Un protocollo basato sul DH ha esattamene questa proprietà, la chiave a lungo termine serve unicamente per fornire autenticazione nello scambio di messaggi che permette di arrivare a condividere il segreto DH. Se quindi questa chiave a lungo termine viene in mano a qualcuno, questi potrà spacciarsi per una delle due parti, e quindi da quel momento in poi l’esecuzione del protocollo DH autenticato, per esempio IKE, non sarà più sicura. Quello che però non potrà essere fatto da questo attaccante, è riuscire a decifrare precedenti sessioni preregistrate, ricostruendo le chiavi di sessione; ciò non sarà fattibile. Questa indipendenza tra chiavi a lungo termine e chiavi di sessione si chiama Sicurezza in avanti perfetta (PFS: Perfect Forward Secrecy), tutto quello che viene dopo sarà compromesso, ma le sessioni precedenti sono a prova di attacco. Parliamo adesso di Autenticazione. Si può parlare di Autenticazione di Entità o anche Identificazione, quando Identificare vuol dire procurarsi prove che l’identità dichiarata è effettivamente quella reale. Autenticazione del Messaggio significa invece accertarsi della autenticità del messaggio nel senso dell’integrità e provenienza dalla sorgente che dichiara di averlo emesso. Voglio quindi accertarmi che il messaggio sia stato veramente emesso da chi dichiara di mandarmelo e che il messaggio sia conforme a quello che è stato originariamente prodotto da questa entità. Possiamo anche distinguere il tipo di autenticazione in base al punto in cui viene effettuata, per l’Autenticazione Locale, un sistema di elaborazione delle informazione localmente, quindi non interconnesso in rete, effettua autenticazione. Esempio classico è l’autenticazione fatta sul proprio pc, indipendentemente se questo sia connesso alla rete oppure no, ha senso fare autenticazione. L’Autenticazione Diretta invece si ha quando con un sistema di accesso, il proprio PC, ci si connette ad un

Page 76: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 76

sistema remoto, e quest’ultimo ci autentica, o come entità oppure autenticando i nostri messaggi, per esempio un server POP3. Per quanto riguarda l’Autenticazione Indiretta, il sistema al quale io chiedo un servizio, non è quello che effettivamente mi autentica, lui o entrambi ricorreremo ad una terza parte per ottenere in definitiva l’autenticazione di entrambi. In Kerberos esiste per esempio un Key Distribuition Center, e quindi per accedere ad un server applicativo bisogna prima procurarsi delle credenziali che verranno fornite da KDC, e poi presentarsi con queste credenziali al server, quindi c’è una terza parte che interviene per l’autenticazione. In tutti questi casi l’autenticazione è fatta realtime, nel momento in cui l’entità chiede accesso ad un servizio o ad una risorsa, viene autenticata. Ci può essere però anche autenticazione offline, nel senso che non è necessario che l’autenticazione avvenga in quel momento, ma essendo avvenuta precedentemente, è possibile presentare le credenziali che sono state rilasciate in maniera permanente o semipermanente, il tipico esempio sono i certificati rilasciati dal CA. Definiamo ora che cosa si va ad autenticare, in che modo viene fatto ciò. Ci sono diversi modi per eseguire autenticazione, quello più usato è l’utilizzo di Password o PIN, specialmente per l’autenticazione delle persone, in cui delle stringhe di caratteri, più o meno vincolate, permettono l’accesso alle risorse. Un altro modo è l’Autenticazione basata sull’indirizzo, cioè vedo da dove viene effettuata la richiesta di autenticazione, da quale indirizzo, e sulla base di questo si viene autenticati. Una possibilità molto più sofisticata, che vedremo più in dettaglio, è quella basata su protocolli crittografici, che comporta operazioni di configurazione preliminare e, all’atto dell’autenticazione, l’esecuzione di un protocollo, cioè uno scambio di messaggi certamente più complessi di quelli scambiati con l’autenticazione su base Password o PIN. Infine ci sono metodi di autenticazione basati sull’utilizzo di mezzi fisici, quali lettori biometrici o Security Tokens. Si parlerà nel seguito di Autenticazione, ma c’è un altro termine molto utilizzato in questo ambito che è l’Autorizzazione. Per Autorizzazione si intende definire le modalità di utilizzazione di una risorsa da parte di un’entità già autenticata, cioè cosa un’entità può e non può fare con quella risorsa. L’Autorizzazione ha senso se e solo se c’è stata preliminarmente un’Autenticazione, in quanto si decide cosa può fare un’entità solo dopo essersi accertati dell’autenticità di quell’entità. Le due cose sono quindi diverse ma hanno un nesso ben preciso, prima si autentica, poi si autorizza. Parlando poi di come sia possibile autenticare un soggetto umano, le tecniche utilizzate si basano su tre precise domande: cosa sa l’entità, una password, un PIN; cosa possiede l’entità, ad esempio una chiave fisica, una smartcard, un oggetto fisico in possesso dell’entità; chi è l’entità, una caratteristica personale, principalmente quelle biometriche per esempio l’impronta digitale o la lettura dell’iride. Una cosa molto importante da tener presente è che l’autenticazione è un operazione puntuale, cioè in un dato momento viene autenticata un’entità, e appena terminata la procedura di autenticazione, colui che ha autenticato può affermare che quella persona è chi dichiara di essere oppure no. Da quel momento in poi ci può essere un istante in cui l’autenticazione perde la sua validità in quanto ad un certo punto della sessione potrebbe subentrare una seconda entità, più in generale al posto di un processo potrebbe subentrarne un altro. Per ovviare a ciò si potrebbe ripetere periodicamente il processo di autenticazione, oppure stabilire una chiave di sessione autentica con lo stesso processo utilizzato per autenticare l’entità, ed usare da quel momento in poi quella chiave di sessione per scambiare i messaggi tra le due entità. Questo tipo di meccanismo si chiama Authenticated Key Establishment. Per quanto riguarda le Password sappiamo che vengono utilizzate per autenticare persone, questo perché per un essere umano è molto più semplice memorizzare una sequenza sensata di caratteri alfanumerici, piuttosto che una stringa di valori esadecimali. L’attacco a forza bruta sulle password si distingue in due possibilità, online e offline. Per il primo l’attaccante si connette con l’entità che chiede di essere autenticata, e prova a catturarne la chiave (trial&error), è possibile contenere tale attacco mediante provvedimenti di rallentamento e/o blocco dell’utenza, anche se bisogna stare molto attenti nel definire questi provvedimenti, bilanciando tra la protezione dell’utente e la possibilità di attacchi DOS (Denial of Service). In tempo reale, online, contenere attacchi alla password diviene più gestibile, in quanto si è costretti ad interagire con il sistema, quindi si è sotto controllo. L’attacco veramente pericoloso è quello offline, in cui

Page 77: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 77

qualcuno cattura delle informazioni e poi con calma, senza che nessuno lo sappia, tenta di indovinare la password. L’attacco offline tipico si chiama Attacco a Dizionario perché si basa sul presupposto che la password non è una stringa casuale, quindi viene compilato un dizionario più o meno ampio delle stringhe che mi aspetto essere password, e poi li provo tutti. La password sotto molti aspetti è proprio come una chiave, quindi ha bisogno di essere inizializzata, ma ha bisogno anche di una memorizzazione sicura. L’autenticazione può essere diretta

Alice fornisce le sue credenziali e viene autenticata; oppure il segreto di Alice è residente in un secondo server di autenticazione

In questo modo, pagando in termini di ritardo sul processo, si semplifica molto la gestione, in quanto ho centralizzato in una o poche macchine la residenza dei segreti. In più, ogni volta che ho necessità di aggiornare quelle informazioni, lo farò su una o poche macchine, che oltretutto potrò proteggere particolarmente anche a livello fisico, restringendone proprio l’accessibilità. In questo modo nei server che verranno di seguito aggiunti, dovrò configurare solo l’indirizzo del server di autenticazione, o meglio inizializzare un canale sicuro tra loro ed il server di autenticazione. L’utilizzazione base di una password, come abbiamo detto, è l’autenticazione di persone. Molto spesso però, a valle di questa operazione, si utilizza la password stessa per derivare chiavi crittografiche. Questo è il modo per esempio per garantire la continuità della validità di una autenticazione, derivando proprio le chiavi di sessione da questa sorta di Master Key che è la password. Se si possiede, per esempio, una chiave di lunghezza n bit, e da questa viene prodotta una chiave di 128 bit, la sicurezza di questa chiave, o meglio la complessità di un attacco a forza bruta su questa chiave, è di 2n, in quanto la sicurezza risiede sempre e solo nella password. Per complicare la ricerca durante un attacco, quello che posso fare è rendere più complicata la funzione che deriva dalla password la chiave di sessione. Per fare ciò si usano due tecniche: il Salt e lo Stretching, il primo è una quantità che può essere anche nota, una stringa binaria, mentre per il secondo è necessario fare delle operazioni che semplicemente aggiungono complessità computazionale. Ad esempio, partendo da una password tradotta in binario p, e dal salt s, una stringa ad esempio di 256 bit, si fa la seguente cosa:

x0=0; xi = h(xi–1 || p || s), i=1,..,r (e.g. r=220); K=xr prendendo quindi come chiave l’ultima iterazione del processo di stretching. Tutto ciò, giocando su r, si può rendere tollerabilmente veloce per l’utente legittimo, ma ha il pregio di rallentare un attacco a dizionario. Per chiarire il ruolo del salt vediamo un esempio di come memorizzare le password. È chiaro che c’è un problema su come memorizzare le password, se un server che deve fornire autenticazione memorizza le password in chiaro, per tutto il tempo che le tiene in memoria queste password saranno esposte ad eventuali attacchi al db del server. Il server dovrebbe quindi proteggere in maniera accurata questo db ed evitare che chiunque lo legga. Un modo molto utilizzato per rimuovere questa debolezza, è memorizzare non la password in chiaro, ma una sua trasformazione irreversibile (ad esempio il suo hash). Catturando il db delle password, in questo caso, ho del materiale che dipende dalle password e che utilizzerò per fare Password guessing in modalità offline, utilizzerò quindi l’hash della password per verificare il mio tentativo di indovinare. Molte persone spesso sono portate ad utilizzare delle password deboli, ad esempio di pochi caratteri. Ci sono diversi modi per contrastare ciò, un modo possibile prevede che sia il sistema stesso a scegliere per

Page 78: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 78

noi le password da utilizzare, e periodicamente le rinfresca. Questa politica pur risultando molto valida, porta invece ad avere delle carenze in quanto la password poi deve comunque essere consegnata alla persona, e se questa non è di facile memorizzazione, porta l’utente a conservarla in luoghi non troppo sicuri come ad esempio i post it incollati sui monitor. Un’altra possibilità invece è quella di permettere all’utente di scegliere la password, però ci sarà un processo che in background farà delle verifiche provando a fare degli attacchi a dizionario. Ogni volta che questi attacchi avranno successo si notificherà all’utente di scegliere un’altra password. Tale meccanismo non è molto efficiente in quanto richiede uno sforzo di calcolo notevole, interazioni con gli utenti, che potrebbero tra l’altro non gradire tutto ciò. Un modo molto pratico invece, consiste nel far scegliere la password all’utente, guidandolo però nella scelta tramite delle indicazioni di massima su come conviene scegliere una password. In seguito verificare online la password scelta, nel momento in cui l’utente la seleziona, per chiedere eventualmente in quel momento di ripetere la scelta. Per capire allora qual è il livello di sicurezza di una password, possiamo modellare la persona che deve scegliere una password, come una sorgente di informazione che emette caratteri appartenenti ad un alfabeto finito. Dato un alfabeto ad n caratteri, il formulatore di password è una sorgente caratterizzabile, supponiamo, da una sua statistica del primo ordine, cioè la probabilità che all’i-mo carattere dica k. Dato cioè un alfabeto A={a1,…,an}, una sorgente statisticamente indipendente è descritta dalla sua probabilità pk = P(X(t)=ak), dove X(t) corrisponde al t-imo carattere emesso. È possibile caratterizzare l’informazione emessa dalla sorgente S, mediante l’entropia media della sorgente, (misurata in bit/simbolo),

H(S) = -∑k pk log2pk

che mi dice quanti bit di informazione per ogni simbolo emette la sorgente; l’entropia sarà massima, H(S)≤log2n , quando i caratteri sono equiprobabili. In definitiva l’entropia misura la riduzione di incertezza che si ha, a seguito dell’acquisizione dell’informazione relativa a quella sorgente. Supponiamo che le password si possano scrivere in caratteri ASCII stampabili, considerando 7 bit ne risultano 95, in quanto i primi 32 sono caratteri di controllo, e il 127 è un carattere speciale. Supponiamo allora che la sorgente formi le password pescando a caso i caratteri tra questi 95, indipendentemente l’uno dall’altro. In questo caso l’entropia media risulta essere di H=log295=6,57 bit/char. Per far si che la quantità di informazione dentro una chiave di 128 bit casuali, sia proprio 128 bit, il numero di caratteri scelti come sopra, deve essere pari a 128/6,57≈20 char. in effetti però dei 95 caratteri se ne usano solo 62, quindi l’entropia si riduce a H=log262=5,95 bit/char, ed aumenta così il numero dei caratteri da inserire come password. Di peggio però c’è che la sorgente, cioè noi, non emette caratteri senza memoria, ma li emette in maniera legata, le cosiddette passphrase, che hanno un qualche significato logico, che ovviamente ha poco di casuale. Questo tipo di sorgente, detta con memoria, è modellata in questo modo: data una sequenza di L caratteri, la probabilità congiunta del vettore finale x di L caratteri è p(x), e la funzione di entropia sarà

HL(x) = -∑ xЄAL p(x)·log2p(x) e l’entropia media per carattere si calcola come H(S) = limL―›∞ HL(x)/L Quindi ad esempio per la lingua italiana, in una password di 6 caratteri, l’entropia media per carattere risulta essere H6(x)/6 ≈1,87 bit/char, scegliendo una password di 6 caratteri è come se avessi scelto una password di circa 12 bit. Parlando quindi di attacchi alle password, quello principale è il Guessing, che è l’attacco a forza bruta, che prova a indovinare la password da un dizionario, in modalità online oppure offline. Poi ci sono altri attacchi, come per esempio l’ascolto (sniffing) sulla rete, perché spesso le password viaggiano in chiaro, oppure se esiste un software malevolo (trojan horse program) dentro la macchina che rilascia le password, nel momento in cui viene inserita questa viene catturata. Altra possibilità è il cosiddetto phishing, quando cioè si riesce ad ottenere le credenziali direttamente dal soggetto interessato, tramite dei trabocchetti. Per contrastare gli attacchi online è utile per esempio mettere dei vincoli sul ritmo con cui è possibile effettuare tentativi, per esempio si lasciano fare 3 tentativi distanziati da 1 secondo, se tutti e tre falliscono si mette un timeout ad esempio di 1 min, oppure si fa crescere esponenzialmente il tempo tra una risposta

Page 79: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 79

errata e la successiva. Il tutto comunque va sempre fatto considerando un buon bilanciamento tra la protezione dell’utente e la possibilità di attacchi DOS (Denial of Service).

LEZ. 20 – 28/11 (prima parte)– Autenticazione: password –

Protocolli di Autenticazione (Security Handshake).

Abbiamo parlato delle password come uno dei meccanismi di autenticazione basilari per le persone, in quanto il loro pregio è quello di essere facilmente memorizzabili da un essere umano, mentre il loro ovvio difetto è la debolezza dal punto di vista della sicurezza. Esiste comunque in questo caso il solito problema della inizializzazione, cioè della distribuzione iniziale. Ci sono vari modi di far questo, dalla consegna fisica della password, a modalità che prevedono la registrazione online con successivo invio della password sulla propria casella di posta, o configurazioni di password direttamente tramite interfaccia web. Ovviamente tutto questo risulta insicuro nel momento in cui lo si fa, in quanto se non si condivide alcun’altro segreto con l’altra entità, inevitabilmente la password viaggerà in chiaro. Un altro modo di inizializzare prevede ad esempio l’apertura di un’utenza con password associata di tipo pre-configurato, secondo una regola comunicata all’interessato, ad esempio una password con durata limitata (pre-expired password), che servirà per attivare quella definitiva. Le password vengono usate talvolta per autenticazione diretta, altre volte per derivarne una chiave, una Master Key, e poi quella si utilizza come una chiave crittografica. Per derivare una chiave da una password basta definire una regola di conversione tra la stringa di caratteri alfanumerici, password, ed una stringa in binario, chiave, secondo un tipo di codifica stabilito. Dopodiché questa stringa binaria verrà posta in ingresso ad una funzione hash o altro, per derivare altre stringhe binarie che fungeranno da chiavi di sessione. Altra modalità di autenticazione riferita sia a persone che dai processi applicativi, è l’autenticazione su base indirizzo. Vado a verificare l’identità dell’entità che chiede accesso alla risorsa, sulla base dell’indirizzo dal quale appare provenire la richiesta. Fatto questo devo poi effettuare un controllo di autorizzazione. Per ogni messaggio che arriva quindi, si verifica una terna <address, remote account name, local account name>, che servirà a verificare innanzitutto se l’utente locale esiste, dopodiché verifica se tra gli indirizzi abilitati all’accesso per quell’utente locale c’è l’indirizzo che gli si presenta. Gli indirizzi abilitati saranno presenti nelle Access Control List, che dovranno essere inizializzate ed aggiornate. Ovviamente tutto ciò non va bene se non si hanno indirizzi fissi, ma funziona bene se ci si trova ad esempio all’interno di una rete privata strutturata, dove c’è un’unica autorità di gestione che fa un piano di indirizzamento privato. Un modo robusto, dal punto di vista della sicurezza, per fare autenticazione è quello di usare protocolli crittografici. Quelli finalizzati in particolare ad autenticazione di entità, possono subire fondamentalmente due tipi di attacco: con Alice e Bob che comunicano, l’attacco passivo consiste nell’ascoltare ciò che è in transito, e catturo informazioni sufficienti per impersonare Alice. L’altro attacco mira ad impadronirsi della base di dati presente nel server Bob, e prendo informazioni sufficienti per impersonare Alice. Questi attacchi sono difficili da contrastare, a meno di poter utilizzare meccanismi di crittografia a chiave pubblica. Un esempio classico di ciò è il protocollo one way authentication (poiché si autentica solo Alice) Challenge-Response

La risposta R sarà un numero random per garantire la freschezza del messaggio di firma che riceverà Bob, in più Bob sarà sicuro dell’autenticità dell’entità Alice, in quanto per effettuare una firma, verificata come

Page 80: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 80

valida, devo usare la chiave privata di Alice. Il presupposto per ciò è che Bob conosca la chiave pubblica autentica di Alice. Nella crittografia a chiave simmetrica invece, un modo di autenticazione molto banale prevede l’invio di identità e password

Il server memorizza la password di Alice, quindi ciò soccombe ad ogni tipo di attacco, tanto che per prima cosa non memorizzerò la password bensì il suo hash, ma impadronendosi del db del server un attaccante può fare comunque password guessing offline. Per prima cosa allora non manderò la password in chiaro, bensì condivido con Bob una chiave segreta S, e ciò potrei farlo anche condividendo una password da cui entrambi deriveremmo una chiave segreta.

Condividendo il segreto S, il protocollo può funzionare esattamente come prima a sfida e risposta, Alice si presenta, viene sfidata, e calcola una quantità che dipende dalla sfida e dal suo segreto. Questo mi rende robusto rispetto ad attacchi di evesdropping (intercettazioni) in quanto catturerei due numeri random R,X, per me inutili. Soccombo però ad attacchi al db in quanto dovrò memorizzare il segreto di Alice. Tutto ciò riguarda il discorso dell’autorizzazione diretta tra le due entità A e B, ma ciò non esclude comunque la presenza di terze parti su cui fare riferimento per semplificare il problema dell’autenticazione. Per semplificare la distribuzione delle chiavi quindi utilizzerò i Key Distribuition Center (KDC), per quanto riguarda la crittografia a chiave simmetrica, mentre per la crittografia a chiave pubblica utilizzerò le Certification Authority (CA). L’uso dei KDC abbassa la complessità da O(n2) ad O(n), e a costo di avere una procedura un po’ più complicata ogni utente potrà comunicare con canale sicuro con un altro utente. Introducendo architettura centralizzata però lo svantaggio è quello di aver creato un singolo punto di fallimento, infatti se il KDC va fuori servizio viene negato qualsiasi altro servizio che richiedeva autenticazione. Altro problema è la formazione di un collo di bottiglia verso il KDC, oppure la compromissione dell’intero sistema qualora venissero catturati i dati memorizzati nel KDC. Per quanto riguarda la CA l’inizializzazione è la stessa, devo riuscire a trasferire agli utenti un’informazione certa, cioè la chiave pubblica autentica della CA, mentre per il KDC devo far condividere alle due parti una chiave segreta. La differenza sostanziale è che l’informazione distribuita col KDC deve essere mantenuta segreta e questo ne complica la distribuzione, in più il KDC deve necessariamente essere online in quanto sia Alice che Bob per comunicare tra di loro devono preventivamente comunicare con il KDC. Una volta entrato in possesso della chiave pubblica autentica della CA, e qualcuno mi manda una richiesta firmata dalla CA, non ho bisogno di contattare la CA in quanto ho già la sua chiave pubblica e posso quindi verificare la sua firma. Non è necessario quindi che la CA sia online, anche se in questo modo non sono però in grado di gestire le revoche. Però non essendo necessaria la presenza online, se ho un fuori servizio della CA il sistema non si blocca, ciò che non posso fare è emettere nuovi certificati. Ed ancora se viene compromessa la CA, verranno emessi dei certificati fasulli, ma i certificati emessi precedentemente sono buoni ed utilizzabili, e nessuna informazione di sicurezza relativa a sessioni precedenti viene compromessa. Detto questo è possibile immaginare un contesto di intermediari multipli organizzati a livello gerarchico e che si fidano gli uni degli altri, e questo vale sia per i KDC sia per le CA. Un esempio è mostrato di seguito

Page 81: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 81

I due presupposti di questo schema sono che Alice precondivide una chiave segreta con il CIA’s KDC, mentre Boris la condivide con il KGB’s KDC. Alice comunica al proprio KDC la volontà di parlare con Boris appartenente ad un KDC remoto, e riceve dal suo KDC un messaggio, cifrato con la loro chiave segreta, contenente una nuova chiave segreta e l’indirizzo del KDC remoto. Tutto questo dopo aver verificato di conoscere questo KDC remoto. Notare che il primo messaggio potrebbe non essere autentico, ma tanto non c’è nessun rischio, poiché il secondo messaggio potrà essere decifrato solo da Alice autentica. A questo punto il KDC di Alice, che condivide una chiave segreta con il KDC remoto, lo avverte di tutto ciò fornendogli la nuova chiave segreta fornita anche ad Alice. Il tutto verrà cifrato con la chiave segreta condivisa da entrambi i KDC. Quando il KDC remoto di Boris riceve il messaggio da Alice, deve generare una chiave segreta Alice-Boris da fornire ad entrambi. Dopo averla generata, la fornirà ad Alice cifrando il messaggio con la chiave segreta Knew che condivide con Alice, mentre cifrerà il messaggio per Boris con la chiave segreta che loro solamente condividono. A questo punto Alice e Boris condividono la medesima chiave e possono comunicare con un loro canale sicuro. Uno degli inconvenienti di tutto ciò è la necessità di un fastidioso sincronismo per evitare confusione tra i vari messaggi, quindi in realtà non si farà proprio così. Infine brevemente vediamo come la autenticazione può essere delegata. Ciò avviene quando Alice, che può autenticarsi al server Bob, vuol far si che una terza parte, Fred, acceda a Bob anche se non ha le credenziali per farlo. Allora chiede al KDC di rilasciare un cosiddetto Ticket a favore del suo amico Fred. Il KDC prima di tutto autentica Alice, verifica anche che Alice sia abilitata a fare deleghe, dopodiché produce un Ticket, un messaggio cifrato, che contiene l’identificativo di Fred, l’identificativo di chi lo ha delegato, Alice, e tutto ciò che riguarda la caratterizzazione di questo permesso temporaneo (da quando a quando vale, vale per cosa). Tutto ciò verrà mandata ad Alice e cifrato con una chiave che solo il KDC conosce, e che quindi Fred non potrà leggere, ma soltanto mostrare al KDC al momento della richiesta di accesso. Esempi di protocolli di autenticazione Vedremo ora in particolare protocolli basati soltanto sul Login, quelli cioè che utilizzano schemi di sfida e risposta, protocolli di Autenticazione Mutua e di Autenticazione Mediata, il primo riguarda A e B soltanto, senza terze parti, mentre gli altri due coinvolgono terze parti, KDC nell’autenticazione mutua, e la CA in quella mediata. Ci sono poi i protocolli robusti con le password, Strong Password Protocol, quelli pensati proprio per ovviare al fatto che usando le password, un attaccante potrebbe leggere la password in chiaro in transito oppure trovarla memorizzata nel sistema, e quindi questi protocolli cercano di risolvere questi due problemi.

Page 82: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 82

Protocollo Login-only con Secret Key. Tra i vari modi di effettuare autenticazione (Password, Indirizzo, Protocolli crittografici), parliamo ora di Autenticazione fatta mediante protocolli crittografici. Avendo una chiave segreta, lo scenario è quello in cui Alice, un client, chiede a Bob, un server, di autenticarsi, utilizzando il classico schema di sfida e risposta

Alice dichiara la sua identità, riceve una sfida R che è un numero random, e risponde mandando il risultato di un algoritmo, che può essere tranquillamente noto, in cui come ingresso debbono esserci almeno il numero random R ricevuto come sfida e la chiave segreta condivisa tra le due entità. Bob, che ha memorizzata nel suo db la chiave segreta condivisa, quando riceve la quantità X=f{KAB,R}, verifica che venga uguale a quella che lui stesso può calcolare, in questo caso autenticherà Alice. L’autenticazione è valida in quanto Alice ha mandato a Bob un messaggio fresco X=f{KAB,R}, in quanto ha utilizzato il Nonce R appena ricevuto da Bob, in più Alice è l’unica altra entità che conosce la chiave KAB. Eventuali problemi che possono sorgere sono: essendo una autenticazione one-way, Alice prova la sua identità, ma il server Bob no, quindi Alice non sa con chi ha parlato. Se un Intruder, un attaccante può fare Address Spoofing, cioè spacciarsi per Bob, Alice non saprà mai di non aver parlato con Bob, non ha modo di saperlo. Un altro problema riguarda il fatto che, poiché il fatto che Alice si autentichi al server è soltanto la premessa di una sessione, se nel resto della sessione non c’è qualche altro meccanismo di autenticazione successivo al primo, quello che può succedere è che un attaccante faccia il cosiddetto Session Hijacking (hijacking: fare l’autostop). Trudy, l’intruder, lascerà che Alice si autentichi correttamente, in quanto lui non sa farlo, dopodiché facendo address spoofing, taglierà fuori Alice e mettendosi al suo posto continuerà la sessione. Questo succede solo se il resto della sessione non è crittograficamente legato alla fase di autenticazione. Ciò potrebbe avvenire derivando, nella fase di autenticazione, delle chiavi ausiliarie da utilizzare per fare autenticazione di messaggio piuttosto che cifratura dei messaggi, durante tutta la sessione. Ovviamente se il db di Bob è compromesso, con questo tipo di protocollo, chi cattura il db di Bob può impersonare Alice, perché conosce il segreto. Un esempio ancora più semplice è quello basato su di un solo messaggio

Alice e Bob condividono sempre una chiave segreta, e invece di mandare la password in chiaro, viene inviato un messaggio contenente la cifratura di qualche cosa di riconoscibile da parte di Bob. Per riconoscibile si intende che ciò che viene cifrato deve essere qualcosa di predicibile, non random, altrimenti qualunque cosa Bob tira fuori dovrebbe prenderla per buona, ma potrebbe essere qualcosa cifrato con una chiave differente, e quindi dall’altra parte non ci sarebbe Alice. Quello che si utilizza quindi è il tempo, un timestamp, quindi Bob, decifrando, verifica che il tempo ricevuto rientri in un intervallo di tempo, determinato dal proprio clock ± il clock skew, cioè la tolleranza ammessa tra i due clock. Trudy potrebbe spacciarsi per Alice, aprendo un’altra sessione, se riesce, nell’intervallo di tolleranza, a replicare lo stesso messaggio appena inviato da Alice, in quanto Bob si accontenta di verificare che il messaggio rientri dentro l’intervallo. Quindi bisogna mantenere un fastidioso compromesso tra, evitare l’intervallo di vulnerabilità all’impersonazione, e d’altro canto mantenere una tolleranza che non renda troppo critico il sistema dal punto di vista della sincronizzazione. In più c’è anche il problema che i clock vanno protetti, in quanto un altro possibile attacco potrebbe fare in modo di portare indietro il clock del server, e mandare successivamente un vecchio messaggio intercettato precedentemente. Altro meccanismo di protezione da parte del server Bob, sarebbe quello di memorizzare, ad ogni passata autenticazione che cade nel clock skew, il timestamp. Quindi per ogni singolo utente, Bob dovrebbe memorizzare i timestamps di tutte le

Page 83: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 83

richieste di autenticazione che cadono nel clock skew, per verificare che tra tutte quelle non ce ne sia una che si ripete. Quello che invece si può fare di molto più robusto è utilizzare uno schema di sfida e risposta con paradigmi a chiave pubblica

L’ulteriore vantaggio di questo schema è che, non solo l’intercettazione non fa guadagnare nulla a Trudy, ma il db di Bob non contiene nulla di critico, in quanto contiene solo la chiave pubblica autentica di Alice. Questo db va quindi protetto, ma soprattutto rispetto alla modifica dei dati. Se qualcuno è in grado di manomettere questo db modificandone i dati, potrebbe sostituire la chiave pubblica di Alice con un’altra chiave pubblica, e far credere a Bob che quella è la chiave autentica di Alice. In questo modo farebbe saltare tutta l’autenticazione.

LEZ. 21 – 28/11 (seconda parte)– Protocolli di Autenticazione (Security Handshake).

Introduciamo il protocollo di Autenticazione Mutua, un protocollo cioè che permette ad Alice di autenticarsi verso Bob ma anche il viceversa. Un modo semplice di ottener questo è replicare, invertito, il paradigma di sfida e risposta, quindi Alice e Bob condividono una chiave segreta KAB.

Alice si dichiara a Bob, Bob la sfida con un Nonce RB, e Alice costruisce il risultato di un algoritmo che ha come input chiave segreta condivisa con Bob e il Nonce appena ricevuto, che potrebbe per esempio essere un MAC. Dopodiché per autenticare Bob si fa esattamente la stessa cosa, è Alice a sfidare Bob e quest’ultimo risponde, e questo raggiunge l’obiettivo di un’autenticazione mutua. Tutto ciò è alquanto inefficiente in quanto vengono usati cinque messaggi quando ad Alice, per autenticare Bob, ha bisogno di mandargli una sfida, e ciò poteva farlo benissimo prima. Il tutto si risolve quindi con tre soli messaggi

Al momento di dichiararsi, Alice manda anche il Nonce RA, in modo che Bob può rispondere con il suo Nonce, sfidando Alice, e con la risposta alla sfida di Alice, il risultato dell’algoritmo che ha come ingresso il Nonce inviatogli da Alice, e la chiave segreta che condividono. Alice a questo punto risponderà semplicemente alla sfida di Bob con f(KAB,RB). Risolvendo il problema di efficienza in questo modo, però, il tutto non funziona, nel senso che è facile mettere su un attacco che si chiama di Riflessione. Il contesto reale in cui avviene questo è Alice client e Bob Server, quindi bisogna tener conto del fatto che Alice deve poter aprire più sessioni con il Server, in maniera del tutto normale. L’errore commesso riguarda il fatto che una buona regola prevede di non far fare ad Alice e Bob le stesse cose cioè, per mostrare di conoscere la chiave segreta, utilizzano lo stesso

Page 84: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 84

algoritmo, con la stessa chiave, e la sfida come input. In questo caso, un attacco a riflessione prevede che Trudy, spacciandosi per Alice, apre una sessione con Bob mandando RX

Bob risponde con R1 e con una stringa random che è il risultato dell’elaborazione di un algoritmo f con la chiave segreta KAB, che Trudy non conosce, e con RX. Trudy quindi sa che la stringa random sarà il risultato di un algoritmo noto che ha come secondo argomento la quantità da lui scelta, ma non è in grado ora di rispondere alla sfida di Bob. A questo punto Trudy, subito dopo il secondo messaggio, e prima di inviare la risposta alla sfida di Bob, apre una seconda sessione

verso Bob, spacciandosi di nuovo come Alice, e mandando come sfida proprio R1, la sfida ricevuta precedentemente da Bob, e quest’ultimo rispondendo non fa altro che rispondere lui stesso alla precedente sfida inviata a Trudy nel secondo messaggio della prima sessione. La seconda sessione a questo punto fallirà, e Bob non saprà mai il perché, mentre la prima andrà a buon fine, purché il terzo messaggio venga inviato a Bob in un tempo sufficiente a far mantenere a Bob la prima sessione aperta. Per ovviare a questo problema basta differenziare le risposte tra le due parti, per esempio non facendo usare la stessa chiave, due chiavi indipendenti piuttosto che due chiavi derivate. Per esempio Bob potrebbe usare KAB+1 oppure KAB xor F0F0F0F0F0F0F0F016, messa cioè in xor con una stringa di 1 e 0 alternati. In questo modo Trudy, dovendo usare una chiave KAB modificata, che non conosce, non sa rispondere a Bob. Un altro modo sarebbe quello di specificare che l’iniziatore della procedura invia un Nonce dispari mentre il secondo deve rispondere con un Nonce pari, quindi Trudy, inviando di nuovo un Nonce pari, non otterrebbe alcuna risposta. Le due sfide insomma non devono essere strutturalmente identiche. Nello schema inefficiente a 5 messaggi, l’attacco a riflessione non sarà possibile in quanto Trudy, prima di ricevere la risposta alla sua sfida, deve autenticare la sua identità rispondendo alla sfida di Bob, e questo non lo sa fare. Un’altra regola da rispettare quindi, è che il primo ad autenticarsi deve essere sempre chi inizia il protocollo. Tutto questo con chiave simmetrica, se invece ci mettiamo nel paradigma a chiave pubblica, il presupposto è che ognuno delle due entità conosce la chiave pubblica autentica dell’altra.

Il protocollo quindi può essere sempre a sfida, e fatto in tre passi. Alice si dichiara e manda una sfida, Bob risponde mandando qualcosa che è firmato con la sua chiave privata, in modo che Alice può autenticarlo, ed una sfida. Alice a sua volta risponderà firmando con la propria chiave privata. In questo caso i due algoritmi sono diversi poiché l’input non è la stessa chiave KAB, ma sono due chiavi diverse, quindi questo impedisce l’attacco a riflessione. Normalmente tutto questo rappresenta la premessa per stabilire quello che si definisce un canale sicuro, cioè un canale in cui scambiarsi qualcos’altro, dei messaggi, che verranno mandati almeno autenticati, eventualmente anche cifrati. Per creare un canale sicuro bisogna quindi creare delle chiavi di sessione. Tale chiavi, come requisito, devono essere inerenti a quella sessione, quindi legate per esempio ai Nonce che ci si

Page 85: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 85

è scambiati. Devono essere derivabili solo dalle due parti in gioco, quindi dipendenti dalle loro chiavi segrete, e non debbono essere ovviamente predicibili in alcun modo. Nel caso di crittografia simmetrica per esempio, visto che il protocollo funziona inviando sfide, ognuna delle due entità, chiuso il protocollo positivamente, utilizza i Nonce appena scambiati, RA, RB, e la chiave KAB per derivare le chiavi di sessione, utilizzando RA, RB, e KAB come input di un nuovo algoritmo g, diverso da f. Nel caso di autenticazione a chiave pubblica, arrivando per gradi a quella che è la soluzione più robusta, Alice e Bob si autenticano mutuamente ognuno conoscendo la chiave pubblica dell’altro. Dopo essersi autenticati quindi, Alice sceglie un numero a caso, lo cifra con la chiave pubblica di Bob, e lo invia a quest’ultimo. Alice sceglie quindi la chiave di sessione Ks e la manda a Bob, cifrando questa, con la chiave pubblica autentica di Bob, in questo modo solo Bob può decifrarla e conoscere questo numero. Il difetto base di questo è che normalmente conviene che la chiave sia concordata, e non scelta da una delle parti e mandata all’altra. Infatti Ks cifrata con la chiave pubblica di Bob può essere mandata da chiunque, basta aspettare che Alice si autentichi con Bob. Per evitare ciò allora Alice firmerà questo messaggio con la sua chiave privata, in modo da garantire l’autenticità dell’entità che ha emesso il messaggio. In quel momento Trudy non può fare niente, ma un possibile problema si verifica se Trudy, dopo aver registrato tutta la conversazione che segue, in un secondo momento, riesce ad impadronirsi del server Bob, in particolare della sua chiave privata. A questo punto tornerà indietro a prendere quel particolare messaggio che contiene la chiave di sessione, e decifrandolo catturerà così Ks. Cioè se in un determinato momento la chiave segreta di Bob viene compromessa vi sono problemi non solo per il futuro, ma anche per tutto quello che potrebbe essere stato registrato fino a quel momento. Questo deriva dal fatto che ho lasciato che una delle due parti, per esempio Alice, scegliesse la chiave. In effetti qualcosa di più robusto può prevedere ad esempio che Alice invia a Bob una quantità, un nonce NA, ovviamente firmato con la propria chiave, e Bob fa altrettanto. Quindi tutti e due mandano una quantità random, e tutti e due la firmano, con la propria chiave privata, dopo averla cifrata con la chiave pubblica dell’altro. Quindi tutti e due possono verificare che il messaggio provenga dalla controparte che hanno appena autenticato, possono decifrare in quanto posseggono la propria chiave privata, e fatto ciò calcoleranno una certa funzione g(NA,NB), e da questa tireranno fuori una certa chiave di sessione. Quindi ad esempio la chiave di sessione sarà il risultato, per esempio di un hash, della giustapposizione di NA e NB, che, essendo cifrati, non possono essere letti da nessuno. Il problema di prima è anche superato, nel senso che, se successivamente qualcuno si impadronisce della chiave segreta di Bob, tornando in dietro, potrà venire a conoscenza di NA, ma non del’altro nonce. Non sarà quindi in grado di ricostruire la chiave. Ovviamente questo presuppone che, una volta creata la chiave di sessione, i server debbono aver cura di distruggere i due nonce NA e NB, e finita la sessione, distruggano anche la chiave Ks. Tutto ciò ha ancora il difetto che se l’attacante fosse così formidabile da catturare le chiavi private di tutte e due le entità, allora effettivamente potrebbe ricostruire le chiavi di sessione. Per rendere impossibile anche questo è necessario che i due facciano un Diffie-Hellman, autenticato poiché ormai si sono autenticati. Eseguendo quindi uno scambio DH, non solo si ottiene sicurezza rispetto ad intercettazioni realtime, ma anche se in un futuro un attaccante riuscisse a prendersi entrambe le chiavi private, comunque non potrebbe ricostruire le chiavi di sessione. In realtà, infatti, i numeri che si scambiano Alice e Bob nel DH, non sono neanche cifrati, proprio perché non è per nulla critica la loro confidenzialità. Per calcolare la chiave segreta, si utilizzano quei numeri random NA e NB, ma non si mandano proprio questi, si manda infatti una loro trasformazione che è sign(prKA,gNA mod p) da parte di Alice, e sign(prKB,gNB mod p) da parte di Bob, che grazie alla complessità del DL non permette di calcolare NA e NB, e la chiave di sessione sarà data da KAB = gNANB . In questo modo anche catturando le chiavi private di Alice e Bob, non si riuscirà mai a ricostruire le chiavi di sessione passate, sempre che Alice e Bob abbiano avuto cura di buttare via NA, NB e KS. Quindi quello che normalmente si fa, se si desidera effettivamente una sessione con una cosiddetta Sicurezza Perfetta in avanti, è autenticarsi mutuamente, eseguire un Diffie-Hellman, con il quale si concordano una o più chiavi relative alla sessione, e poi eseguire la sessione, con crittografia a chiave simmetrica, utilizzando le chiavi appena concordate, andando a fare cifratura, autenticazione o quello che serve.

Page 86: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 86

Questo garantisce non solo che, essendoci autenticati, l’autenticazione rimane garantita nel tempo (non ci può essere hijacking) in quanto sto usando una chiave di sessione concordata tramite le chiavi master. Ma garantisce anche che le sessioni sono indipendenti una dall’altra e totalmente indipendenti dalle chiavi master. Vediamo ora un esempio di Autenticazione mediata, l’esempio più classico e noto, il Needham and Schroeder. Fin qui abbiamo visto autenticazione one-way diretta, senza intermediari, i presupposti sono che Alice e Bob condividono a chiave segreta, oppure Alice e Bob conoscono la chiave pubblica autentica dell’altro. Nel primo caso, se ci sono n di questi Alice e Bob, e vogliono comunicare come gli pare tra loro, allora Alice dovrebbe condividere la chiave segreta con ognuna della controparti, quindi n chiavi segrete, e questo varrebbe per ognuno di loro. In tutto quindi si dovrebbero inizializzare n(n-1)/2 chiavi segrete, che al crescere di n cresce quadraticamente è può diventare un numero infattibile. Si prevede quindi un intermediario, un Key Distribution Center, e il presupposto in questo caso è che ogni utente condivide una chiave segreta propria con il KDC, quindi le chiavi da inizializzare diventano n. L’obbiettivo rimane sempre quello di permettere ad Alice e Bob di autenticarsi mutuamente e di creare un canale sicuro tra loro, partendo dalla situazione iniziale in cui ognuno di loro condivide soltanto una chiave segreta con un certo intermediario di cui si fidano.

Tutto inizia con Alice che contatta il KDC fornendo tre parametri, il proprio identificativo, l’identificativo di Bob, e il Nonce N1, che serve al solito per garantire freschezza. Quando il KDC risponde, manda un messaggio cifrato con la chiave segreta che condivide con Alice, quindi se chi riceve non è Alice, vede essenzialmente una stringa random. Per garantire la freschezza del messaggio, il KDC inserisce anche il nonce N1, e lo inserisce modificato, cioè cifrandolo sempre con la chiave condivisa con Alice. Nel messaggio che il KDC manda ad Alice ci sarà poi la chiave di sessione KAB, ed un ticket da presentare a Bob. Questo ticket conterrà l’identità di Alice e la chiave di sessione scelta dal KDC, cifrati con la chiave segreta che Bob condivide con il KDC. Dal punto di vista di Alice, quindi, il ticket apparirà come una stringa random. A questo punto Alice si presenta finalmente a Bob, con un messaggio contenente il ticket, ed un nuovo nonce firmato con la chiave di sessione scelta dal KDC. Bob ricevendo il ticket proverà a decifrarlo con la chiave segreta che condivide con il KDC, in quanto solo così sarà sicuro che quel messaggio è stato originato proprio dal KDC, anche se ancora non sa chi è che lo sta contattando adesso. Con la chiave di sessione che troverà nel ticket, Bob decifrerà N2, e sfiderà ora il mittente del messaggio per vedere se è proprio Alice, come dichiarato nel ticket. A questo punto Alice può autenticare Bob in quanto, fidandosi del KDC, sa che solo Bob avrebbe potuto decifrare il ticket che lei hai ricevuto dal KDC ed inviato al probabile Bob, e risponde poi alla sfida inviatale da Bob. Quando Bob riceve l’ultimo messaggio, è in grado di autenticare Alice, in quanto questa gli ha dimostrato di conoscere la chiave di sessione KAB, e di conoscerla ora in quanto gli ha risposto alla sfida del nonce N3. Poiché Bob ha trovato KAB nel ticket cifrato con la chiave che condivide con il KDC, fidandosi proprio del KDC Bob è in grado di autenticare Alice. Quanto detto ha come vulnerabilità il fatto che Alice, una volta entrata in possesso del ticket, non ha più bisogno di contattare il KDC, e questo è un problema. Supponiamo che, eseguita con successo una sessione, tempo dopo la chiave che Alice condivide con il KDC venga compromessa, a questo punto si modifica la

Page 87: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 87

configurazione del KDC inserendo una nuova chiave condivisa con Alice. Colui che ha catturato la vecchia chiave di Alice con il KDC, non è tagliato fuori, in quanto avendo registrato dei vecchi round di protocollo, può decifrarli e tirare fuori un vecchio ticket con il quale presentarsi a Bob. Quindi anche cambiando la chiave tra Alice ed il KDC, il meccanismo di autenticazione non è al sicuro, e questo perché manca il fattore tempo, e Bob non ha modo di sapere se il ticket è stato appena ottenuto. Un provvedimento semplice inserirebbe dei timestamps, mentre uno più radicale prevede di complicare il protocollo nel seguente modo

rendendolo in tre fasi, secondo lo schema Needham and Schroeder Esteso. Prima Alice contatta Bob, poi contatta il KDC, poi ricontatta Bob. Il primo contatto serve essenzialmente a garantire a Bob la freschezza del ticket che si otterrà, nel secondo contatto Alice fornirà al KDC il nonce ricevuto da Bob, e questo non può essere sicuro che l’abbia mandato proprio Bob, in quanto decifrandolo esce un numero random, però va avanti e fornisce il quarto messaggio ad Alice in cui vi è il ticket. Nel terzo contatto si svolge tutto come prima, però a questo punto Bob è sicuro della freschezza del ticket in quanto ritrova il nonce che aveva precedentemente inviato ad Alice, anche se questa non era riuscita a verificarlo in quanto cifrato con la chiave che Bob condivide con il KDC. Questo è un modo in cui ancora non c’è il tempo, sto guadagnando il vantaggio che non ho bisogno di orologi più o meno sincronizzati su tutti questi apparati, ma sto perdendo nel fatto che il protocollo si è complicato alquanto. Una nuova variante è lo schema di Otway-Rees, che riporta a cinque messaggi mantenendo però la struttura come prima, cioè prima Alice contatta Bob, Bob contatta il KDC e poi ricontatta Alice, e si ottiene comunque mutua autenticazione e la garanzia per Bob e Alice che la sessione si stia svolgendo ora, e che non ci siano messaggi replicati.

Lo scopo di questo protocollo è ottimizzare poiché riduce il numero di messaggi, però alla fine le garanzie che ottiene sono le stesse. Altro modo di risolvere il problema di non rendere i ticket spendibili per sempre è, in maniera più naturale, inserire il fattore tempo in questo protocollo, che è quello che si fa in Kerberos. Si utilizzano dei Timestamps, e si assume che Alice, Bob e KDC abbiano degli orologi sincronizzati entro una certa tolleranza. Si aggiungono poi, tra i vari campi del ticket, altri due campi che danno l’istante di inizio e l’istante di fine di validità del ticket stesso. Bob quindi, prima di accettare il ticket, può verificare che l’istante del suo clock sia interno a questo intervallo, cioè che il ticket in quell’intervallo sia valido. In più poi, in Kerberos, si fa

Page 88: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 88

un’ulteriore ottimizzazione, dividendo in due entità il KDC, un server di lungo termine, e dei server che danno ticket di secondo ordine. In questo modo si ottiene un ticket, di validità più lunga, che serve a generare altri ticket, e poi ogni volta che si ha bisogno di un ticket per un server, lo si chiede ad un Ticket Granting Server, cioè una macchina che, presentando il ticket a lungo termine (diciamo l’abbonamento), fornisce i ticket che mi permettono di accedere al server. Questo serve a sgravare il carico del KDC centralizzato ed a rendere più robusto il sistema. Diamo ora un ultimo cenno ai Protocolli basati su Password irrobustiti. Tali protocolli, a parte il caso banale in cui memorizzo e mando in chiaro la password, prevedono almeno di non memorizzare in chiaro la password, usando ad esempio l’hash di questa, oppure evitano di mandarla in chiaro. Rimane però il fatto che entrambe le cose sono difficili da attuare, a meno di ricorrere a sistemi un po’ più sofisticati. Uno di questi è il cosiddetto Lamport’s hash, che presenta il seguente schema

e che si basa unicamente sull’uso di una funzione hash. Alice si autentica a Bob in modalità one-way, il che ovviamente, come sempre in questi casi, apre dei varchi a possibili attacchi, in quanto Alice non è mai sicura di parlare con Bob. Il presupposto in questo caso è che Alice conosce la sua password e, seduta alla workstation, chiede accesso al server. Il server in questo caso memorizza, per ogni utente, una tripla di dati che sono: un numero intero n, una stringa che può essere anche nota, il salt, e poi Zn=hn(Y) cioè l’applicazione ripetuta n volte dell’hash di una certa stringa Y=pswd || salt || Bob, formata cioè dalla password utente, dal salt, e dall’identità del server. A questo punto Alice viene sfidata dal Server che le invia l’intero n, il salt e il servername, e lei, conoscendo la password, compone la stringa Y e vi calcola sopra n-1 volte l’hash, e manda tutto al server. A questo punto il server fa l’hash della stringa X, e poi la confronta con il valore Zn che ha memorizzato in corrispondenza di Alice, se il confronta ha esito positivo può autenticare Alice, e rimpiazza la terna precedentemente memorizzata con la nuova terna [n-1; salt; X]. Questo vuol dire che il numero di accessi è limitato, e dopo un numero di accessi bisogna re inizializzare n. Va notato che se qualcuno si impossessa del db del server, non può impersonare Alice in quanto conoscerebbe solo l’hash n volte della password, e la password non viaggia neanche in chiaro. Ma se intercetto X e sono in possesso del db del server, potrei fare un attacco a forza bruta sulla password facendo l’hash di X e ricerca dolo nel db. Oltre al numero di accessi limitato, un altro problema riguarda lo Small n attack, cioè spacciandosi per Bob, Trudy potrebbe fornire un n basso ad Alice, ad esempio 20, e lei risponde con h19, da quel momento in poi, per 80 volte di seguito, Trudy si può autenticare, utilizzando l’h19(Y) che non avrebbe dovuto sapere, e applicandoci sopra un numero appropriato di volte h. utto questo viene fuori perché il protocollo non è a mutua autenticazione, infatti non autenticando Bob, Alice non è sicura dell’identità di colui con cui sta parlando. Oltre al fatto del difetto di dover prima o poi re inizializzare n. Vediamo infine un ultimo protocollo contenuto nello standard RFC 2945, chiamato SRP Secure Remote Protocol, un esempio di protocollo basato su password, che è robusto sia contro l’intercettazione, sia contro la cattura del db del server.

Page 89: Appunti di Sicurezza nelle Comunicazioni+Index · Appunti di Sicurezza nelle Comunicazioni AA 2007/2008 G.M. pag. 6-La segretezza (o confidenzialità), causando una diffusione impropria

A p p u n t i d i S i c u r e z z a n e l l e C o m u n i c a z i o n i A A 2 0 0 7 / 2 0 0 8 G.M. pag. 89

Troviamo sempre Alice e Bob, e poi dei parametri pubblici noti, un numero primo p, e una quantità g che è un elemento primitivo di ordine q di Zp*. Si suppone che Alice conosca una password w, mentre Bob si memorizza la coppia (Alice, gW mod p) , dove gW è una quantità che dipende dalla password, ma in maniera tale che non è possibile risalirvi in quanto significherebbe risolvere il problema del logaritmo discreto. Alice allora genera un numero random a, e manda la quantità ga mod p, di risposta Bob genera un numero random b e manda la quantità gb+gW mod p, u, cB. Tutto ciò somiglia molto al Diffie-Hellman, si stanno scambiando dei numeri che non c’è neanche bisogno di proteggere, e che serviranno a calcolare una chiave segreta, e stanno facendo ciò senza autenticarsi, almeno per adesso. La variante è che Bob sta mandando qualcosa che per poter conoscere c’è bisogno di gW mod p. A questo punto Bob calcola la seguente chiave segreta K=gb(a+uW) mod p, basata sul b random che ha scelto lui, su ga mod p che ha ricevuto da Alice, e su guW mod p con u numero a 32 bit. Allo stesso modo Alice ha i mezzi per calcolare la stessa chiave, e lo fa prima di iniziare l’autenticazione, che avviene secondo il solito paradigma Challenge-Response utilizzando la chiave che entrambi hanno creato. In questo modo si sta provando che in questo istante, utilizzando quindi dei nonce, sia Alice che Bob conoscono una certa chiave segreta K, per conoscere la quale bisognava per forza conoscere la password ovvero conoscere la quantità gW mod p dipendente dalla password, e allo stesso tempo conoscere il b segreto. Questo fornisce sicurezza in avanti in quanto come in un Diffie-Hellman ho prodotto una chiave di sessione non del tutto indipendente dalla password, ma se anche catturo la password non sono in grado di costruirla in quanto non conosco gli a e b random che sono stati utilizzati, se verranno distrutti subito dopo. Il vantaggio di tutto ciò è che se qualcuno catturasse il database potrebbe fare password guessing, ma non può in nessun modo impersonare Alice poiché non conosce quel w di cui Alice ha bisogno per autenticarsi.