Salta al contenuto
Note per Studenti Crittografia asimmetrica, RSA e TLS

Crittografia asimmetrica, RSA e TLS

In questa pagina 8

La crittografia asimmetrica

Definizione (crittografia asimmetrica). Detta anche a chiave pubblica. Usa chiavi diverse per cifrare e decifrare. La chiave di cifratura è pubblica e può essere visibile a tutti; la chiave di decifratura è privata, tenuta segreta da ogni nodo e conservata in registri protetti dall'hardware. Le due chiavi sono generate da un metodo che calcola una coppia corrispondente: sono legate matematicamente.

Se il mittente A vuole scrivere a B, indicando con vBv_B la chiave pubblica di B e con sBs_B la sua chiave privata:

C=EvB(P),P=DsB(C).C=E_{v_B}(P),\qquad P=D_{s_B}(C).

Proprietà richieste:

  • gli algoritmi di cifratura e decifratura sono facili da calcolare;
  • è computazionalmente facile generare una coppia di chiavi;
  • è computazionalmente impraticabile ricavare la chiave privata dalla corrispondente chiave pubblica;
  • dati il testo cifrato e la chiave pubblica, è impraticabile ricostruire il testo in chiaro.

Per cifrare si usa la chiave pubblica (che chiunque può avere): dopo la cifratura il messaggio è rimescolato e nessuno lo capisce senza la chiave privata corrispondente. La riservatezza è garantita perché solo il destinatario B conosce la propria chiave privata. Chi intercetta ottiene il testo cifrato e accede alla chiave pubblica, ma non riesce a ricostruire il messaggio.

Esempio. In una rete di n=100n=100 persone servono 100100 coppie di chiavi, una per persona (e non (1002)=100⋅992=4950\binom{100}{2}=\frac{100\cdot99}2=4950 chiavi segrete come nella crittografia simmetrica, Funzioni hash e crittografia simmetricaLa crittografia trasforma un messaggio in chiaro (plaintext) in un testo cifrato (ciphertext) con una chiave: C = E_ke(P), P = D_kd(C); può dare riservatezza, integrità e autenticazione. Attacchi: solo testo cifrato, testo in chiaro noto, testo in chiaro scelto, forza bruta. Funzione hash: mappa dati di qualsiasi lunghezza in un digest di lunghezza fissa; one-way (dato h è difficile trovare m con hash(m) = h) e resistente alle collisioni; famiglie MD (MD5 rotto per le collisioni nel 2004) e SHA (SHA-0 e SHA-1 rotti, SHA-2 il più usato, SHA-3); costruzione di Merkle-Damgård; usi: integrità e password. Crittografia simmetrica: stessa chiave segreta per cifrare e decifrare; Cesare (E_n(x) = x + n mod 26), Vigenère, Enigma; DES (blocchi da 64 bit, chiave da 56) e AES (blocchi da 128 bit, chiavi da 128, 192, 256); modi ECB (insicuro), CBC, CFB, OFB, CTR. Scambio della chiave con Diffie-Hellman: K = g^(xy) mod p. MAC e HMAC: autenticazione con chiave condivisa.Funzioni hash e crittografia simmetrica →: lì ogni coppia di persone ha una chiave segreta propria, e le coppie non ordinate di 100100 persone si contano con il coefficiente binomialeil numero di modi di scegliere 2 elementi da n senza badare all'ordine è n(n-1)/2Fattoriale e coefficienti binomiali →), e ciascuno può pubblicare la sua chiave pubblica su un sito. Ma una chiave pubblica va distribuita e il suo legame con il proprietario va certificato: lo fanno i certificati.

Certificati digitali

Se un messaggio è cifrato con la chiave pubblica di qualcuno, solo la sua chiave privata lo decifra. Le chiavi pubbliche però devono essere distribuite in qualche modo, e il collegamento tra proprietario e chiave deve essere certificato: ci deve essere un rapporto di fiducia tra chiave pubblica e privata. I certificati digitali servono a questo.

Definizione (certificato digitale). Un certificato è gestito da una terza parte, la Certificate Authority (CA). Per ottenerlo, un'entità fornisce alla CA la propria identità e la propria chiave pubblica; la CA convalida l'identità ed emette il certificato. Il certificato contiene: il nome dell'entità proprietaria e la sua chiave pubblica; la validità o scadenza; la CA che l'ha emesso (e molti altri dati). È firmato con la chiave privata della CA: chiunque abbia la sua chiave pubblica può verificare il certificato.

Esempio (come nelle slide). Visitando https://www.google.com, il browser controlla automaticamente il certificato digitale inviato da Google. Un certificato reale contiene: nome del sito www.google.com; chiave pubblica (una lunga stringa casuale); emittente (Google Trust Services LLC, la CA); periodo di validità (per esempio da marzo 2025 a marzo 2026); firma della CA, che prova che è legittimo. Il browser lo controlla: se è valido pensa "questa chiave pubblica appartiene davvero a Google", e può cifrare i dati verso Google in sicurezza.

Il browser verifica la firma con la chiave pubblica della CA, che a sua volta ha un certificato firmato da una CA di livello superiore, fino a una CA radice il cui certificato è già nell'elenco del sistema operativo o del browser (catena di fiducia); controlla anche le date di validità e che il nome del sito corrisponda a quello del certificato.

Firma digitale

Se un messaggio è cifrato con la propria chiave privata, chiunque abbia la chiave pubblica può verificare che sia stato proprio il proprietario a mandarlo. La firma digitale serve a questo e garantisce:

  • autenticità (il messaggio viene davvero dal mittente);
  • integrità (il messaggio non è stato alterato);
  • non ripudio (il mittente non può negare in seguito di averlo mandato).

Definizione (firma digitale). Fase 1, firma: si calcola l'hash del messaggio (con una funzione hash crittografica come SHA-256, Funzioni hash e crittografia simmetricaLa crittografia trasforma un messaggio in chiaro (plaintext) in un testo cifrato (ciphertext) con una chiave: C = E_ke(P), P = D_kd(C); può dare riservatezza, integrità e autenticazione. Attacchi: solo testo cifrato, testo in chiaro noto, testo in chiaro scelto, forza bruta. Funzione hash: mappa dati di qualsiasi lunghezza in un digest di lunghezza fissa; one-way (dato h è difficile trovare m con hash(m) = h) e resistente alle collisioni; famiglie MD (MD5 rotto per le collisioni nel 2004) e SHA (SHA-0 e SHA-1 rotti, SHA-2 il più usato, SHA-3); costruzione di Merkle-Damgård; usi: integrità e password. Crittografia simmetrica: stessa chiave segreta per cifrare e decifrare; Cesare (E_n(x) = x + n mod 26), Vigenère, Enigma; DES (blocchi da 64 bit, chiave da 56) e AES (blocchi da 128 bit, chiavi da 128, 192, 256); modi ECB (insicuro), CBC, CFB, OFB, CTR. Scambio della chiave con Diffie-Hellman: K = g^(xy) mod p. MAC e HMAC: autenticazione con chiave condivisa.Funzioni hash e crittografia simmetrica →); si cifra l'hash con la chiave privata: questa è la firma; si manda il messaggio insieme alla firma. Fase 2, verifica: il ricevente calcola da sé l'hash del messaggio; decifra la firma ricevuta con la chiave pubblica del mittente; se hash decifrato == hash calcolato, il messaggio è autentico.

La firma cifra con la chiave privata (e può verificare chiunque); la cifratura riservata usa la chiave pubblica del destinatario (e solo lui legge): i ruoli sono opposti. Si firma l'hash e non l'intero messaggio perché è corto e il calcolo è veloce. Il confronto con il MAC è nella tabella di Funzioni hash e crittografia simmetricaLa crittografia trasforma un messaggio in chiaro (plaintext) in un testo cifrato (ciphertext) con una chiave: C = E_ke(P), P = D_kd(C); può dare riservatezza, integrità e autenticazione. Attacchi: solo testo cifrato, testo in chiaro noto, testo in chiaro scelto, forza bruta. Funzione hash: mappa dati di qualsiasi lunghezza in un digest di lunghezza fissa; one-way (dato h è difficile trovare m con hash(m) = h) e resistente alle collisioni; famiglie MD (MD5 rotto per le collisioni nel 2004) e SHA (SHA-0 e SHA-1 rotti, SHA-2 il più usato, SHA-3); costruzione di Merkle-Damgård; usi: integrità e password. Crittografia simmetrica: stessa chiave segreta per cifrare e decifrare; Cesare (E_n(x) = x + n mod 26), Vigenère, Enigma; DES (blocchi da 64 bit, chiave da 56) e AES (blocchi da 128 bit, chiavi da 128, 192, 256); modi ECB (insicuro), CBC, CFB, OFB, CTR. Scambio della chiave con Diffie-Hellman: K = g^(xy) mod p. MAC e HMAC: autenticazione con chiave condivisa.Funzioni hash e crittografia simmetrica →. Un esempio numerico con RSA è più sotto.

Richiami di aritmetica modulare

Un intero nn si scrive come n=q⋅d+rn=q\cdot d+r, con qq quoziente, dd modulo (divisore), rr resto: n mod d=rn\bmod d=r.

Esempi (come nelle slide). Addizione: 27 mod 6=327\bmod6=3. Sottrazione: 6 mod 4=26\bmod4=2. Moltiplicazione: 21 mod 6=321\bmod6=3. Esponenziazione: 81 mod 4=181\bmod4=1.

Addizione, sottrazione, moltiplicazione ed esponenziazione si comportano come ci si aspetta (modulo dd).

Perché si può ridurre prima di operare. Se a=q1d+r1a=q_1d+r_1 e b=q2d+r2b=q_2d+r_2 (con r1=a mod dr_1=a\bmod d, r2=b mod dr_2=b\bmod d), allora a b=(q1d+r1)(q2d+r2)=d (q1q2d+q1r2+q2r1)+r1r2,a\,b=(q_1d+r_1)(q_2d+r_2)=d\,(q_1q_2d+q_1r_2+q_2r_1)+r_1r_2, cioè a ba\,b e r1r2r_1r_2 hanno lo stesso resto modulo dd: (a b) mod d=((a mod d)(b mod d)) mod d(a\,b)\bmod d=\big((a\bmod d)(b\bmod d)\big)\bmod d. Lo stesso vale per la somma. È la regola che permette di non far mai crescere i numeri: dopo ogni prodotto si riduce modulo dd e si resta sotto dd. Esempio con N=3233N=3233: 652=4225=1⋅3233+99265^2=4225=1\cdot3233+992, quindi 652≡99265^2\equiv992; per 65465^4 non si calcola 422524225^2 ma 9922=984064=304⋅3233+1232992^2=984064=304\cdot3233+1232, quindi 654≡1232(mod3233)65^4\equiv1232\pmod{3233}. Calcolare gag^a vuol dire moltiplicare gg per se stesso aa volte (non è efficiente in questo modo, ma esistono algoritmi efficienti, come le potenze ripetute).

Potenze ripetute (square-and-multiply). Si scrive l'esponente in binario (Sistemi di numerazione posizionaliNotazione posizionale in base b; conversioni tra base 10, 2, 8 e 16 per interi (divisioni successive) e per parti frazionarie (moltiplicazioni successive); numeri periodici in binario.Sistemi di numerazione posizionali →) e si calcolano i quadrati successivi g, g2, g4, g8,…g,\,g^2,\,g^4,\,g^8,\dots (ciascuno è il quadrato del precedente, ridotto modulo dd); poi si moltiplicano, sempre riducendo, solo i quadrati che corrispondono alle cifre 11. Esempio: 17=100012=16+117=10001_2=16+1, quindi g17=g16⋅g1g^{17}=g^{16}\cdot g^{1}, e g16g^{16} richiede 44 quadrati: in tutto 55 moltiplicazioni al posto di 1616. In generale un esponente di kk bit richiede al massimo 2k2k moltiplicazioni modulari: per 2753=10101100000122753=101011000001_2 (1212 bit, cinque cifre 11) sono 1111 quadrati e 44 prodotti, 1515 moltiplicazioni invece di 27522752; con un esponente di 20482048 bit sono al massimo circa 40004000 moltiplicazioni invece di un numero di operazioni con più di 600600 cifre decimali. La divisione funziona diversamente: si usa l'inverso modulare.

Definizione (inverso modulare). b−1b^{-1} è l'inverso modulare di bb modulo dd se b⋅b−1≡1(modd)b\cdot b^{-1}\equiv1\pmod d. Esiste se gcd⁡(b,d)=1\gcd(b,d)=1 (cioè se bb e dd sono coprimi); quindi, se d=pd=p è primo, ogni intero tra 1 e p−1p-1 ha un inverso modulo pp. La divisione modulare è (a/b) mod d=(a⋅b−1) mod d(a/b)\bmod d=(a\cdot b^{-1})\bmod d.

Come si trova l'inverso: algoritmo di Euclide esteso. L'algoritmo di Euclidesi calcola il MCD dividendo ripetutamente: la coppia (a, b) diventa (b, a mod b) finché il resto è 0 e l'ultimo resto non nullo è il MCDCiclo while → dà il gcd⁡\gcd con una sequenza di divisioni con resto; risalendo le divisioni all'indietro si scrive il gcd⁡\gcd come combinazione 1=x b+y d1=x\,b+y\,d. Riducendo modulo dd resta x b≡1x\,b\equiv1, cioè xx è l'inverso. Se il gcd⁡\gcd è diverso da 11 questa combinazione non esiste e l'inverso non c'è.

Esempio: inverso di b=17b=17 modulo d=3120d=3120 (serve in RSA, sotto).

  1. Divisioni (ciascuna usa come divisore il resto della precedente): 3120=183⋅17+93120=183\cdot17+9; 17=1⋅9+817=1\cdot9+8; 9=1⋅8+19=1\cdot8+1. L'ultimo resto non nullo è 11: gcd⁡=1\gcd=1, l'inverso esiste.
  2. Si risale: 1=9−81=9-8; poiché 8=17−98=17-9, 1=9−(17−9)=2⋅9−171=9-(17-9)=2\cdot9-17; poiché 9=3120−183⋅179=3120-183\cdot17, 1=2(3120−183⋅17)−17=2⋅3120−367⋅171=2(3120-183\cdot17)-17=2\cdot3120-367\cdot17.
  3. Modulo 31203120 il termine 2⋅31202\cdot3120 vale 00, quindi −367⋅17≡1-367\cdot17\equiv1 e 17−1≡−367≡3120−367=275317^{-1}\equiv-367\equiv3120-367=2753.

Esempio. b=4b=4, d=7d=7: deve valere 4⋅b−1≡1(mod7)4\cdot b^{-1}\equiv1\pmod7, quindi b−1=2b^{-1}=2, infatti 4⋅2=8≡14\cdot2=8\equiv1. b=5b=5, d=11d=11: b−1=9b^{-1}=9, infatti 5⋅9=45=4⋅11+1≡15\cdot9=45=4\cdot11+1\equiv1. Divisione: (8/4) mod 5=(8⋅4−1) mod 5(8/4)\bmod5=(8\cdot4^{-1})\bmod5; poiché 4−1=4(mod5)4^{-1}=4\pmod5 (4⋅4=16≡14\cdot4=16\equiv1), =(8⋅4) mod 5=2=(8\cdot4)\bmod5=2. Altri: (8/3) mod 5=1(8/3)\bmod5=1, (11/4) mod 5=4(11/4)\bmod5=4 (verificati con Python). La divisione per 0 non è ammessa.

Definizione (logaritmo discreto). Se ba≡y(modd)b^a\equiv y\pmod d, allora log⁡by=a\log_b y=a è il logaritmo discreto. Non si conosce alcun algoritmo in tempo polinomiale per calcolarlo.

Esempio. b=5b=5, d=7d=7, y=4y=4: 5a≡4(mod7)5^a\equiv4\pmod7. Le potenze di 5 modulo 7 sono 5,4,6,2,3,15,4,6,2,3,1 per a=1,…,6a=1,\dots,6: 52≡45^2\equiv4, quindi a=2a=2. Con dd di 2048 bit non si può più provare.

RSA

Il Diffie-Hellman (Funzioni hash e crittografia simmetricaLa crittografia trasforma un messaggio in chiaro (plaintext) in un testo cifrato (ciphertext) con una chiave: C = E_ke(P), P = D_kd(C); può dare riservatezza, integrità e autenticazione. Attacchi: solo testo cifrato, testo in chiaro noto, testo in chiaro scelto, forza bruta. Funzione hash: mappa dati di qualsiasi lunghezza in un digest di lunghezza fissa; one-way (dato h è difficile trovare m con hash(m) = h) e resistente alle collisioni; famiglie MD (MD5 rotto per le collisioni nel 2004) e SHA (SHA-0 e SHA-1 rotti, SHA-2 il più usato, SHA-3); costruzione di Merkle-Damgård; usi: integrità e password. Crittografia simmetrica: stessa chiave segreta per cifrare e decifrare; Cesare (E_n(x) = x + n mod 26), Vigenère, Enigma; DES (blocchi da 64 bit, chiave da 56) e AES (blocchi da 128 bit, chiavi da 128, 192, 256); modi ECB (insicuro), CBC, CFB, OFB, CTR. Scambio della chiave con Diffie-Hellman: K = g^(xy) mod p. MAC e HMAC: autenticazione con chiave condivisa.Funzioni hash e crittografia simmetrica →) serve a far concordare due parti sulla stessa chiave condivisa, e poi si cifra con un cifrario simmetrico. Nella crittografia a chiave pubblica c'è una seconda idea, la cifratura a chiave pubblica (Public Key Encryption, PKE). L'algoritmo RSA prende il nome dagli inventori Rivest, Shamir e Adleman (1978). Come Diffie-Hellman si appoggia sulla difficoltà del logaritmo discreto, RSA si appoggia sulla difficoltà della fattorizzazione di numeri grandi.

Situazione: il mittente Alice, il ricevente Bob. Obiettivo: generare una chiave pubblica con cui Alice cifra i messaggi per Bob e una chiave privata che aiuta Bob a decifrarli.

Formula (generazione delle chiavi RSA).

  1. Si scelgono due numeri primi grandi pp e qq.
  2. Si calcola N=p qN=p\,q.
  3. Si calcola il totiente φ(N)=(p−1)(q−1)\varphi(N)=(p-1)(q-1), cioè quanti interi tra 11 e N−1N-1 sono coprimi con NN (motivazione sotto).
  4. Si trova un intero positivo e<φ(N)e<\varphi(N) coprimo con φ(N)\varphi(N), cioè gcd⁡(e,φ(N))=1\gcd(e,\varphi(N))=1.
  5. Si calcola d=e−1 mod φ(N)d=e^{-1}\bmod\varphi(N).

e−1e^{-1} esiste, perché ee e φ(N)\varphi(N) sono coprimi; ee e dd sono uno l'inverso modulare dell'altro: d e≡1(modφ(N))d\,e\equiv1\pmod{\varphi(N)} (per costruzione: proprietà P1).

Chiave pubblica di Bob: PK=(N,e)PK=(N,e), comunicata a chiunque voglia scrivergli. Chiave segreta: SK=(N,d)SK=(N,d); le informazioni segrete sono la quaterna SI=(p,q,d,φ(N))SI=(p,q,d,\varphi(N)), che non va condivisa con nessuno.

Formula (cifratura e decifratura RSA). Bob manda a Alice PK=(N,e)PK=(N,e). Alice cifra il messaggio mm (con m<Nm<N): c=Enc(m,PK)=me mod Nc=\text{Enc}(m,PK)=m^e\bmod N. Bob decifra con la chiave segreta: m=Dec(c,SK)=cd mod Nm=\text{Dec}(c,SK)=c^d\bmod N. Il blocco di messaggio può essere al massimo lungo quanto NN.

Perché φ(N)=(p−1)(q−1)\varphi(N)=(p-1)(q-1). Gli interi da 11 a N−1N-1 non coprimi con N=pqN=pq sono quelli divisibili per pp o per qq (gli unici divisori primi di NN). I multipli di pp sono p,2p,…,(q−1)pp,2p,\dots,(q-1)p: sono q−1q-1; i multipli di qq sono p−1p-1; nessun numero è multiplo di entrambi (sarebbe multiplo di pq=Npq=N). Quindi i coprimi sono (N−1)−(q−1)−(p−1)=pq−p−q+1=(p−1)(q−1)(N-1)-(q-1)-(p-1)=pq-p-q+1=(p-1)(q-1). Con p=61p=61, q=53q=53: 3232−52−60=31203232-52-60=3120.

Perché funziona (teorema di Eulero). Per ogni intero (messaggio) mm coprimo con NN vale mφ(N)≡1(modN)m^{\varphi(N)}\equiv1\pmod N. Idea della dimostrazione: siano u1,…,uφu_1,\dots,u_\varphi gli interi coprimi con NN (modulo NN). Moltiplicarli per mm (coprimo) li rimescola senza ripetizioni né uscite dall'insieme: m u1,…,m uφm\,u_1,\dots,m\,u_\varphi sono ancora gli stessi numeri, in un altro ordine. Il prodotto di tutti è quindi lo stesso, mφU≡Um^{\varphi}U\equiv U con U=u1⋯uφU=u_1\cdots u_\varphi, e siccome UU è coprimo con NN si può dividere per UU (inverso modulare), ottenendo mφ≡1m^\varphi\equiv1. Esempio con N=15N=15 (φ=8\varphi=8, coprimi 1,2,4,7,8,11,13,141,2,4,7,8,11,13,14): moltiplicando per m=2m=2 si ottiene 2,4,8,14,1,7,11,132,4,8,14,1,7,11,13, gli stessi numeri; e infatti 28=256=17⋅15+1≡12^8=256=17\cdot15+1\equiv1. Per N=pN=p primo è il piccolo teorema di Fermat, mp−1≡1m^{p-1}\equiv1. Poiché d e≡1(modφ(N))d\,e\equiv1\pmod{\varphi(N)} per P1, si ha d e=1+k φ(N)d\,e=1+k\,\varphi(N) per un certo kk, e quindi

cd≡(me)d=med=m1+kφ(N)=m⋅(mφ(N))k≡m⋅1k=m(modN).c^d\equiv\left(m^e\right)^d=m^{ed}=m^{1+k\varphi(N)}=m\cdot\left(m^{\varphi(N)}\right)^k\equiv m\cdot1^k=m\pmod N.

Passaggi: la prima uguaglianza sostituisce c≡mec\equiv m^e; (me)d=med(m^e)^d=m^{ed} per le regole delle potenze (Esponenziale e logaritmoLa funzione esponenziale a^x (base positiva diversa da 1) e la sua inversa, il logaritmo in base a, con grafici e proprietà.Esponenziale e logaritmo →); ed=1+kφ(N)ed=1+k\varphi(N) viene da ed≡1(modφ(N))ed\equiv1\pmod{\varphi(N)}; m1+kφ=m⋅(mφ)km^{1+k\varphi}=m\cdot(m^{\varphi})^k; e mφ≡1m^\varphi\equiv1 per Eulero.

Il caso di mm non coprimo con NN è rarissimo con NN grande (vuol dire che mm è un multiplo di pp o di qq), ma il risultato vale lo stesso. Se pp divide mm: modulo pp si ha m≡0m\equiv0 e quindi med≡0≡mm^{ed}\equiv0\equiv m; modulo qq, mm è coprimo con qq e per Fermat mq−1≡1m^{q-1}\equiv1, perciò med=m⋅(mq−1)k(p−1)≡mm^{ed}=m\cdot(m^{q-1})^{k(p-1)}\equiv m. Poiché med−mm^{ed}-m è divisibile sia per pp sia per qq, lo è per N=pqN=pq.

Esempio completo (numeri piccoli). p=61p=61, q=53q=53: N=3233N=3233, φ(N)=60⋅52=3120\varphi(N)=60\cdot52=3120. Si prende e=17e=17 (coprimo con 3120=24⋅3⋅5⋅133120=2^4\cdot3\cdot5\cdot13, perché 1717 è primo e non compare tra i fattori) e d=e−1 mod 3120=2753d=e^{-1}\bmod3120=2753 (calcolato con Euclide esteso nella sezione sopra), perché 17⋅2753=46801=15⋅3120+1≡117\cdot2753=46801=15\cdot3120+1\equiv1. Messaggio m=65m=65: c=6517 mod 3233c=65^{17}\bmod3233. Con le potenze ripetute (17=100012=16+117=10001_2=16+1, ogni valore è il quadrato del precedente ridotto modulo 32333233): 652≡99265^2\equiv992, 654≡123265^4\equiv1232, 658≡154765^8\equiv1547, 6516≡78965^{16}\equiv789, quindi 6517=6516⋅65≡789⋅65=51285=15⋅3233+2790≡279065^{17}=65^{16}\cdot65\equiv789\cdot65=51285=15\cdot3233+2790\equiv\mathbf{2790} (per esempio l'ultimo quadrato è 15472=2393209=740⋅3233+7891547^2=2393209=740\cdot3233+789). Decifratura: 27902753 mod 3233=652790^{2753}\bmod3233=65 (verificato con Python; verificato anche 653120≡165^{3120}\equiv1). Chiave pubblica (3233,17)(3233,17), segreta (3233,2753)(3233,2753); il messaggio deve essere minore di 3233.

Sicurezza.

  • Se un attaccante riuscisse a fattorizzare NN in pp e qq, potrebbe calcolare la chiave segreta. RSA è sicuro se e solo se la fattorizzazione degli interi è difficile per quelle scelte di interi.
  • pp e qq si scelgono a caso, devono essere primi e grandi, e NN deve superare i 2048 bit (circa 617 cifre decimali: 22048=102048log⁡102≈10616,52^{2048}=10^{2048\log_{10}2}\approx10^{616{,}5}, Esponenziale e logaritmoLa funzione esponenziale a^x (base positiva diversa da 1) e la sua inversa, il logaritmo in base a, con grafici e proprietà.Esponenziale e logaritmo →) per evitare gli algoritmi di fattorizzazione oggi noti.
  • La struttura del modulo è scelta per evitare attacchi ovvi e non ovvi: per esempio, fare di NN il prodotto di due primi della stessa dimensione evita alcuni attacchi noti (primi da 1500 a 3000 bit).
  • Come per Diffie-Hellman, ci sono molte altre proprietà sottili della generazione delle chiavi e della decifratura che, se implementate male, creano vulnerabilità anche se l'algoritmo sembra semplice.

Padding casuale. Una caratteristica da implementare obbligatoriamente è un riempimento casuale (random padding). Per esempio con RSA PKCS #1 v1.5 il messaggio completato è mp=00  02  [stringa casuale]  00  [m]m_p=\texttt{00}\;\texttt{02}\;[\text{stringa casuale}]\;\texttt{00}\;[m]. La dimensione utile del messaggio diminuisce, per lasciare posto alla stringa di riempimento (il blocco massimo resta NN). Il padding risolve l'attacco a testo cifrato scelto adattivo e dà sicurezza semantica; PKCS #1 v1.5 è molto usato oggi.

Autenticazione con RSA

Si vuole una prova certificata dell'identità di un server o, più formalmente, che (i) un certo documento digitale sia stato generato da un'entità legittima e (ii) non sia stato modificato strada facendo. Il server manda un pacchetto P=[ m∣s ]P=[\,m\mid s\,] con un messaggio mm in chiaro (per esempio un certificato di identità) con in coda una firma digitale ss.

  • il server ottiene la firma ss del messaggio mm usando la chiave segreta SK=(N,d)SK=(N,d): s=md mod Ns=m^d\bmod N;
  • il client verifica che la firma sia corretta con la chiave pubblica PK=(N,e)PK=(N,e): calcola se mod Ns^e\bmod N.

Se il risultato è uguale a mm, è una prova certificata (per la struttura algebrica) che il messaggio è stato firmato dall'entità legittima, l'unica che conosce la chiave segreta.

Esempio (chiavi sopra). Il server firma m=100m=100: s=1002753 mod 3233=1391s=100^{2753}\bmod3233=1391. Il client calcola 139117 mod 3233=100=m1391^{17}\bmod3233=100=m: firma valida. Se il messaggio arrivasse cambiato in m′=101m'=101, il client calcolerebbe 139117 mod 3233=100≠1011391^{17}\bmod3233=100\ne101 e scarterebbe il pacchetto. Con la firma sull'hash (come nella sezione "Firma digitale") si firma h=H(m)h=H(m) al posto di mm: con un hash di valore 4242 si ha s=422753 mod 3233=3065s=42^{2753}\bmod3233=3065 e 306517 mod 3233=423065^{17}\bmod3233=42.

Attacchi a RSA semplice (appendice)

Malleabilità (attacco a testo cifrato scelto adattivo). Con l'RSA "nudo", Mallory può farsi decifrare il messaggio di Alice.

  1. Mallory intercetta il messaggio cifrato c=me mod Nc=m^e\bmod N.
  2. Sceglie un numero casuale aa.
  3. Calcola un nuovo testo cifrato (con la chiave pubblica) c′=c⋅ae mod N=(m a)e mod N=Enc(m a,PK)c'=c\cdot a^e\bmod N=(m\,a)^e\bmod N=\text{Enc}(m\,a,PK).
  4. Manda c′c' a Bob, che lo decifra e ritorna m am\,a a Mallory.
  5. Mallory calcola (m a)⋅a−1 mod N=m(m\,a)\cdot a^{-1}\bmod N=m: ha ottenuto il messaggio.

Il passo 4 dipende dal contesto e dall'applicazione (il server può restituire o no il testo in chiaro), ma ci sono casi pratici in cui succede; la robustezza a questo attacco è oggi un requisito standard per un algoritmo di sicurezza.

Esempio (N=3233N=3233, e=17e=17, m=65m=65, c=2790c=2790). Con a=2a=2: c′=2790⋅217 mod 3233=3017c'=2790\cdot2^{17}\bmod3233=3017. Bob decifra 30172753 mod 3233=130=65⋅23017^{2753}\bmod3233=130=65\cdot2. Mallory ottiene 130⋅2−1 mod 3233=65=m130\cdot2^{-1}\bmod3233=65=m.

Determinismo. L'RSA nudo non è semanticamente sicuro: con la stessa chiave pubblica (N,e)(N,e) e lo stesso messaggio mm il testo cifrato c=me mod Nc=m^e\bmod N è sempre lo stesso, a ogni cifratura successiva.

Contromisura. Alice costruisce mp=m+pm_p=m+p con un riempimento casuale pp. Mallory intercetta c=mpe mod Nc=m_p^e\bmod N, sceglie aa e produce c′=(mp a)e mod Nc'=(m_p\,a)^e\bmod N; Bob lo decifra, elimina il riempimento dal risultato e restituisce un m′≠m am'\ne m\,a; quindi (m′) a−1 mod N≠m(m')\,a^{-1}\bmod N\ne m: il riempimento ha distrutto la struttura algebrica.

Attacco alle firme RSA semplici. Un attaccante vuole ottenere da un server la firma s(m)s(m) di un messaggio mm (conosce PK=(N,e)PK=(N,e)).

  1. Calcola un messaggio apparentemente innocuo m′=(m ae) mod Nm'=(m\,a^{e})\bmod N per qualche aa.
  2. Chiede al server di firmare m′m', ottenendo s(m′)=(m′)d mod Ns(m')=(m')^d\bmod N.
  3. Calcola s(m′)⋅a−1 mod N=(md⋅aed)⋅a−1=md mod N=s(m)s(m')\cdot a^{-1}\bmod N=(m^d\cdot a^{ed})\cdot a^{-1}=m^d\bmod N=s(m), perché aed≡aa^{ed}\equiv a (stessa dimostrazione della decifratura; a−1a^{-1} esiste perché aa è coprimo con NN).

Esempio (m=7m=7, a=2a=2). m′=7⋅217 mod 3233=2565m'=7\cdot2^{17}\bmod3233=2565; il server firma: s(m′)=25652753 mod 3233=2101s(m')=2565^{2753}\bmod3233=2101; l'attaccante ottiene 2101⋅2−1 mod 3233=26672101\cdot2^{-1}\bmod3233=2667, che è proprio s(7)=72753 mod 3233=2667s(7)=7^{2753}\bmod3233=2667: ha una firma su m=7m=7 senza averla mai chiesta. Per questo si firma l'hash con padding (PSS) e non il messaggio nudo.

Dove si mette la sicurezza: applicazione o trasporto

Alcuni protocolli ISO/OSI non offrono funzioni di sicurezza: queste sono realizzate dall'applicazione o da uno dei livelli sotto.

  • Sicurezza a livello applicazione: si può garantire una protezione end-to-end; semplifica i requisiti dei livelli sotto e riduce il costo in dimensione dei pacchetti ed elaborazione, perché l'overhead è introdotto per dato e non per pacchetto.
  • Sicurezza a livello trasporto o rete: lo stesso meccanismo di sicurezza può essere condiviso da più applicazioni.

TLS e SSL

Definizione (SSL/TLS). SSL e TLS (Secure Socket Layer, Transport Layer Security) sono protocolli crittografici che garantiscono una comunicazione affidabile in rete. SSL (3.0) è ancora usato ma ha vulnerabilità note (POODLE) e se ne sconsiglia l'uso; TLS è la versione più recente e più sicura, ed è quella raccomandata. Sono progettati per funzionare con TCP (TCP - connessione, affidabilità e controllo di flussoTCP (Transmission Control Protocol) è il protocollo di trasporto con connessione e affidabile: trasforma il servizio senza connessione e inaffidabile di IP in un flusso di byte ordinato, senza errori né duplicati. La connessione si apre con l'handshake a tre vie (SYN, SYN+ACK, ACK) e si chiude con tre o quattro segmenti (FIN). I byte sono numerati: il numero di sequenza è quello del primo byte del segmento, il numero di ACK (cumulativo) è il prossimo byte atteso. Il mittente può inviare $\min(\text{rwnd},\text{cwnd})$ byte non ancora confermati; rwnd (finestra del ricevitore, in un campo di 16 bit) è il controllo di flusso. L'errore si gestisce con checksum, ACK, timeout di ritrasmissione (RTO) e ritrasmissione rapida dopo tre ACK duplicati. Per usare tutto il canale la finestra deve valere almeno il prodotto banda-ritardo (BDP); il throughput massimo è $\text{MSS}\cdot W_{\max}/\text{RTT}$.TCP - connessione, affidabilità e controllo di flusso →) e usano i certificati per stabilire un collegamento cifrato tra client e server.

Le funzioni principali:

  • autenticare gli estremi e definire l'insieme delle chiavi crittografiche;
  • scambiare dati riservati con la cifratura simmetrica;
  • autenticare i messaggi con un hash sicuro.

Il certificato contiene una chiave pubblica che autentica l'identità del sito o server e permette il trasferimento cifrato dei dati con la crittografia asimmetrica.

Come funziona.

  1. Il client chiede l'accesso a una risorsa protetta su un server.
  2. Il server risponde con il proprio certificato, che include la chiave pubblica e la sua firma.
  3. Il client verifica che il certificato sia valido e fidato (emesso da una CA, non scaduto, firma del server valida): così il server è autentico.
  4. Il client genera una chiave di sessione simmetrica e la cifra con la chiave pubblica del server: la chiave di sessione arriva al server in modo sicuro.
  5. Il server decifra la chiave di sessione con la propria chiave privata.
  6. Le due parti usano la chiave di sessione simmetrica per trasmettere e ricevere i dati su un canale cifrato.

I messaggi (TLS 1.0): (1) ClientHello (cifrari supportati); (2) ServerHello (cifrario scelto); (3) certificato del server + firma; (4) il client verifica il certificato; (5) client key exchange, cifrato con la chiave pubblica del server; (6) il server ottiene la chiave di sessione con la sua chiave privata; (7) Client finished; (8) Server finished; poi i messaggi scambiati sono cifrati con la chiave di sessione condivisa.

Client                                                          Server
  |--(1) ClientHello: cifrari supportati --------------------------->|
  |<-(2) ServerHello: cifrario scelto ------------------------------|
  |<-(3) certificato del server + firma ----------------------------|
  | (4) verifica il certificato                                      |
  |--(5) client key exchange (cifrato con la chiave pubblica) ------>|
  |                          (6) ricava la chiave di sessione con la chiave privata
  |--(7) Client finished ------------------------------------------>|
  |<-(8) Server finished -------------------------------------------|
  |<=============== dati cifrati con la chiave di sessione ==========>|

Chiavi usate.

  • Chiave asimmetrica: la coppia pubblica/privata identifica il server e avvia la sessione cifrata. La chiave privata è nota solo al server; la pubblica è condivisa con il certificato.
  • Chiave di sessione simmetrica: chiavi usa e getta generate per ogni connessione, usate per cifrare e decifrare i dati trasmessi. Sono scambiate in modo sicuro con la cifratura asimmetrica.

Servizi offerti.

Da TLS 1.0 a TLS 1.3

Usare la stessa coppia di chiavi (pubblica, privata) sia per l'autenticazione sia per generare poi la chiave condivisa non si fa più. Motivo: se un attaccante registra tutta la transazione (leggendo i pacchetti che viaggiano in rete), con calma riesce a rompere la chiave (cioè a recuperare la chiave privata del server) e ottiene l'accesso a tutte le transazioni cifrate successive, e anche a quelle già registrate. L'approccio attuale:

  • si usa Diffie-Hellman per generare la chiave condivisa (così la chiave privata del server serve solo a firmare);
  • si riduce la latenza: l'accordo sulle suite crittografiche non è più fatto in un passo a parte.
TLS 1.3
Client                                                            Server
  |--(1) ClientHello [Random, g^c mod p] ------------------------->|
  | (2) K = (g^s mod p)^c           |<-(3) ServerHello [Random, g^s mod p]
  |                                   (4) K = (g^c mod p)^s
  |<-(5) Certificate + Sign(Ks, handshake (1)+(3)), Finished, dati applicativi
  |--(6) Finished ---------------------------------------------------->|
  |--(7) dati applicativi ============================================>|

La chiave Diffie-Hellman KK è generata dopo i primi due messaggi; il certificato (5) è cifrato con KK e la firma contiene i messaggi (1)+(3); i numeri casuali (nonce) nei messaggi Hello garantiscono l'unicità; KsK_s è la chiave privata del server (la pubblica è nel certificato). Con autenticazione del client, il server aggiunge una richiesta di certificato in (5) e il client risponde in (6) con il proprio certificato e una firma Sign(Kc,handshake)\text{Sign}(K_c,\text{handshake}), dove KcK_c è la chiave privata del client.

Esempio numerico (DH nell'handshake, p=23p=23, g=5g=5). Il client sceglie c=6c=6 e manda gc mod p=56 mod 23=8g^c\bmod p=5^6\bmod23=8; il server sceglie s=15s=15 e manda 515 mod 23=195^{15}\bmod23=19. Il client calcola K=196 mod 23=2K=19^6\bmod23=2; il server K=815 mod 23=2K=8^{15}\bmod23=2. Passaggi con le potenze ripetute: 52=25≡25^2=25\equiv2, 54≡45^4\equiv4, 56=54⋅52≡4⋅2=85^6=5^4\cdot5^2\equiv4\cdot2=8; 58≡165^8\equiv16 e 15=8+4+2+115=8+4+2+1, quindi 515≡16⋅4⋅2⋅5=640=27⋅23+19≡195^{15}\equiv16\cdot4\cdot2\cdot5=640=27\cdot23+19\equiv19; infine 19≡−419\equiv-4, 196≡(−4)6=4096=178⋅23+2≡219^6\equiv(-4)^6=4096=178\cdot23+2\equiv2 (e i due calcoli concordano perché (gs)c=gsc=(gc)s(g^s)^c=g^{sc}=(g^c)^s). Da KK si ricavano le chiavi simmetriche dei record. In TLS reale pp è di almeno 2048 bit (oppure si usa Diffie-Hellman su curve ellittiche). Poiché KK è effimero (diverso a ogni connessione e buttato via), la compromissione futura della chiave privata del server non permette di decifrare il traffico registrato (forward secrecy).

Esempio (numero di RTT). Nell'handshake TLS 1.0 ci sono due scambi (messaggi 1-3 e 5-8) prima che i dati siano protetti: 2 RTT; in TLS 1.3 il client manda già la propria parte Diffie-Hellman nel primo messaggio: 1 RTT. Una prima richiesta HTTPS (Livello applicazione - HTTPIl livello applicazione è il più alto della pila: offre servizi all'utente con una connessione logica tra le due applicazioni e riceve servizi solo dal trasporto (DNS, HTTP, e-mail, FTP). Il Web (WWW, nato al CERN nel 1989) è un servizio client-server distribuito di pagine collegate da ipertesti; ogni pagina ha un URL protocollo://host:porta/percorso. HTTP: il client manda una richiesta, il server una risposta, su TCP (server sulla porta 80, client su una porta temporanea); senza stato. Messaggi di testo (riga di richiesta o di stato, intestazioni, riga vuota, corpo), metodi GET, POST, HEAD, PUT, DELETE, codici di stato 2xx-5xx. Una pagina con N oggetti incorporati richiede 2(N+1) RTT con connessioni non persistenti e (N+2) RTT con connessione persistente (trascurando la trasmissione). I cookie danno memoria al protocollo: Set-Cookie nella risposta, Cookie nelle richieste, file nel browser e base di dati nel sito. Un proxy (web cache) tiene le copie delle risposte recenti: meno carico sul server, meno traffico, meno ritardo.Livello applicazione - HTTP →) con RTT=100\text{RTT}=100 ms costa quindi: TCP 1 RTT + TLS 1.3 1 RTT + richiesta 1 RTT =3=3 RTT =0,3=0{,}3 s; con TLS 1.0, 1+2+1=41+2+1=4 RTT =0,4=0{,}4 s.

Le due parti del protocollo.

  • Protocollo di handshake: negozia modi e parametri crittografici, autentica le parti, stabilisce il materiale della chiave condivisa. Il Server Hello include il livello di protocollo di sicurezza, i parametri crittografici scelti dall'elenco del client, un numero casuale combinato con data e ora, l'identificatore di sessione, i metodi di compressione, il certificato digitale (con identità e chiave pubblica di cifratura).
  • Protocollo di record: usa i parametri stabiliti dall'handshake per proteggere il traffico tra gli estremi, dividendolo in una serie di record, ognuno protetto in modo indipendente con le chiavi di traffico.

DTLS (Datagram TLS) è il progetto per funzionare con UDP (Protocollo UDPUDP (User Datagram Protocol) è il protocollo di trasporto senza connessione e inaffidabile: rispetto a IP aggiunge soltanto la comunicazione processo-processo (numeri di porta) e un controllo d'errore facoltativo. L'intestazione è di soli 8 byte (porta sorgente, porta destinazione, lunghezza, checksum). Il checksum copre pseudo-intestazione (indirizzi IP, protocollo 17, lunghezza), intestazione e dati, ed è il complemento a uno della somma a 16 bit; se vale 0 significa "non calcolato", e un risultato 0 si trasmette come 0xFFFF. UDP non ha connessione, numeri di sequenza, controllo di flusso, di errore né di congestione: si sceglie per i messaggi brevi (DNS, DHCP, RIP, SNMP) e per le applicazioni in tempo reale, dove conta non aggiungere ritardo.Protocollo UDP →). Problema: l'overhead di DTLS, perché i protocolli sotto hanno dimensione di pacchetto limitata, e si usano ottimizzazioni dei pacchetti e compressione. DTLS crea un'associazione sicura punto-punto (con un handshake simile a quello di TLS): non è compatibile con le comunicazioni IP multicast. Tre modi di sicurezza: PreSharedKey (i dispositivi conservano chiavi simmetriche pre-condivise), RawPublicKey (i dispositivi hanno una coppia di chiavi pubblica-privata senza certificato), Certificate (i dispositivi conservano un certificato X.509).

La sicurezza a livello di rete (IPsec) è nella nota VPNUna VPN (Virtual Private Network) è una rete privata costruita sopra una rete pubblica (Internet): i nodi comunicano in sicurezza come se fossero in una rete privata, ottenendo autenticazione, riservatezza e integrità senza trovarsi fisicamente nella rete. Architettura: un host designato, il server VPN, ammesso dal firewall; chi sta fuori deve passare dal server e autenticarsi. Un pacchetto IP protetto (cifrato) viene incapsulato come carico di un altro pacchetto IP (IP tunneling). Due modi: IPsec (livello rete, nel kernel; protocolli AH ed ESP, modo tunnel o trasporto, Security Association unidirezionale identificata da SPI) e tunnel SSL/TLS (fuori dal kernel, in un'applicazione su TCP o UDP, il più popolare). Il client e il server VPN stabiliscono il tunnel, vi inoltrano i pacchetti IP destinati all'altro lato e, in ricezione, li rilasciano nella rete privata, usando un'interfaccia virtuale TUN (livello 3) o TAP (livello 2). Autenticazione reciproca: il client autentica il server con un certificato, il server il client con una chiave condivisa (per esempio la password). Una VPN nasconde anche l'indirizzo IP reale e permette di aggirare le restrizioni geografiche.VPN →.

Errori comuni

  • Cifrare con la chiave sbagliata: riservatezza = chiave pubblica del destinatario; firma = chiave privata del mittente.
  • Usare RSA senza padding (deterministico, malleabile), o credere che RSA cifri un file intero: si cifra una chiave di sessione e i dati vanno in simmetrica.
  • Scegliere ee non coprimo con φ(N)\varphi(N) (non esiste dd), o dimenticare m<Nm<N.
  • Dimenticare che i certificati servono a legare l'identità alla chiave pubblica: senza, un uomo in mezzo può dare la propria chiave.
  • Pensare che in TLS la chiave di sessione sia sempre cifrata con la chiave pubblica del server: da TLS 1.3 si ricava con Diffie-Hellman.
  • Confondere TLS (su TCP) con DTLS (su UDP).

Versione ripasso

Lezioni in cui compare

Teoria collegata