PKI, per gli amici Public Key Infrastructure – Parte 1/2

Lo ammetto: nonostante abbia studiato svariate volte gli argomenti certificati, firma digitale, coppia chiavi pubblica/privata, Public Key Infrastructure questi in realtà non mi entrano in mente.

Infatti tutte le volte che devo affrontare questi argomenti in modo un poco più approfondito, devo per forza rileggermi alcune parti dei “sacri testi” sulla materia.

Per questo motivo ho pensato di scrivere queste note, il cui scopo principale è solo quello di avere degli appunti ready-to-use da consultare alla bisogna: li condivido con la speranze che anche Voi li troviate interessanti e utili.

Se così non è.. amen.. passate oltre… Vi assicuro che resisterò ugualmente.

Non ve la predete se la trattazione sarà molto sommaria e magari con qualche imprecisione: non è lo scopo di questo scritto trattare in maniera approfondita l’argomento.

L’intento è solo quello di dare alcune idee sull’argomento in modo semplice ed intuitivo.

Criptatura Simmetrica e Asimettrica

Parlare di PKI significa parlare prima di tutto di cripting.

Criptare un messaggio significata prendere un messaggio in “chiaro” (=clear text), cioè leggibile da tutti, e applicargli un algoritmo matematico che lo rende nascosto (=chiper-text).

Per eseguire questa operazione occorre stabilire prima di tutto un algoritmo da utilizzare (ne sono utilizzati diversi), nonchè una chiave, cioè una sequenza di caratteri da utilizzare con questo (cioè la chiave).

Quando si vorrà ottenere dal chiper-text di nuovo il clear-text (cioè decriptare il messaggio) occorrerà conoscere sia l’algoritmo utilizzato che la chiave utilizzata.

Oss.: L’algoritmo utilizzato è l’informazione meno interessante e comunque semplicemente osservando il chiper-text spesso è possibile riconoscerlo: la cosa veramente importante e “sensibile” è la chiave utilizzata.

Il rapporto tra queste due chiavi (quella usate per criptare il messaggio, e quella da usare per decriptare il realtivo chiper-text) definisce il tipo di algoritmo di crifratura.

Se la chiave è la stessa (cioè la chiave usata per criptare il messaggio è uguale alla chiave che si deve usare per decriptare) si è in presenza di un algoritmo a chiave simmetrica.

Se invece le chiavi sono differenti, si è in presenza di un algoritmo a chiave asimmetrica.

In altri termini alcuni algoritmi di cifratura sono a chiave simmetrica, mentre altri a chiave asimmetrica.

Nel contesto in analisi (PKI) gli algoritmi utilizzati sono tutti a chiave asimmetrica.

Quindi in definitiva per usare un algoritmo a chiave asimmetrica per scambiare i dati tra due entità per prima cosa occorre stabilire un algoritmo tra quelli disponibili per questo tipo di cifratura, e quindi si genera una coppia di chiavi, tra loro correlate, una che sarà usata per criptare il messaggio, e l’altra che sarà usata solo per decriptare il messaggio.

Chiamiamole, per il seguito K1 e K2.

Che sia chiaro: se si cripta un messaggio con K1, questà sarà possibile decriptarlo solo ed esclusivamente usando K2.

Altra cosa importante da sapere è che K1 e K2 sono tra loro accoppiate in modo imprescindibile: se si usa K1 criptare un messaggio, per decriptare lo stesso occorrerà usare la K2 che fa coppia con la prima, e nessun’altra K2 possibile tra quelle accettate dall’agoritmo in uso.

Banale ma direi che è indispensabile da specificare per evitare confusione.

Ultimo ma non ultimo: gli algoritmi a chiave asimmetrica hanno la simpatica “feature” che le chiavi sono tra loro intercambiali: nel senso che se si usa K1 per criptare, devo per forza usare K2 per decriptare (e questo l’abbiamo già detto…), ma similmente posso usare K2 per criptare, e K1 per decriptare.

Disponendo di questa coppia di chiavi (K1 e K2) una è chiamata chiave privata, l’altra chiave pubblica: il perchè di questa nomenclatura sarà chiaro a breve.

Se volete giocare un pò con un algoritmo di cifratura asimmetrica una risorsa molto interessante è Online RSA Encryption, Decryption And Key Generator Tool (vedi linkografia): usando questo sito è possibile utilizzare il famoso algoritmo asimmettrico di cifratura RSA, quindi generare coppie di chiave pubbliche private compatibili, quindi criptare e decriptare messaggi usando questi valori.

Unica nota: l’algoritmo RSA oltre a lavorare con una coppia di chiavi asimmetriche usa anche un valore che indica la dimensione della coppia di chiavi utilizzate (il termine tecnico corretto è RSA Key Size).

Ovviamente maggiori saranno le dimensioni delle chiavi impiegate e più robusto sarà il sistema di cripting: ovviamente occorre considerare come controparte che usare chiavi di grosse dimensioni impegna una maggiore capacità computazionale per le operazioni di cripting/decripting.

Quindi come in ogni cosa occorre trovare un buon compromesso tra tempi di elaborazione/robustezza dell’algoritmo considerando l’ambito di utilizzo.

A proposito di sforzo computazionale: gli algoritmi a chiave simmetrica richiedono una capacità computazionale molto minore rispetto agli algoritmi a chiave asimmetrica.

In altri termini sotto il punto di vista di utilizzo di CPU e RAM costa molto meno usare un sistema di cripting a chiave simmetrica rispetto a un algoritmo a chiave assimmetrica.

Però l’uso di algoritmi asimmettrici introducono altri vantaggi che in realtà superano di gran lunga questo maggiore sforzo computazionale.

Https e gli algoritmi a chiave asimmettrica

Https permette di criptare la comunicazione tra un client (browser) e il server (hosting): è questa il vantaggio che ha in confronto ad Http, dove le comunicazioni transitano in chiaro.

Gli algoritmi utilizzati per queste operazioni di cripting sono, in modo sostanziale, a chiave asimmettrica.

Ma perchè ?

Immaginiamo ora per assurdo che Https usi un algoritmo a chiave simmetrica: questo vorrebbe dire che per ogni sito con cui voglio scambiare in modo criptato dati dovrei entrare in possesso della chiave simmetrica utilizzata dal server per criptare i dati, il che è abbastanza disagevole.

Invece usando un algoritmo a chiave asimmetrica la cosa si risolve in modo più semplice.

Il server cui mi voglio connettere ha creato una coppia di chiavi pubbliche/private.

La chiave privata (=K1) se la tiene per sè, e la chiave pubblica (=K2) la distribuisce a tutti.

In realtà quando Vi connettete a un sito usando il protocollo Https nelle fasi iniziali c’è uno scambio di dati dove il sito fornisce al browser il dettaglio dell’algoritmo da usare per il cripting, nonchè la chiave pubblica da utilizzare.

A questo punto quando si trasmettono dati dal browser verso il sito viene usato l’algoritmo stabilito e la chiave pubblica appena ottenuta: il sito, quindi, alla ricezione dei messaggi in arrivo dal browser sarà in grado di decriptare i messaggi usando la sua chiave privata, che per inciso si è tenuto per sè (ed è associata alla chiave pubblica che distribuisce a tutti).

Anche lo scambio di dati dal server verso il browser avviene in modo similare: il server cripterà i dati usando la chiave privata, e quindi sarà possibile lato browser ricavare i dati in chiaro usando la relativa chiave pubblica (come accennato le due chiavi sono tra loro intercambiabili).

Oss.: Le cose, in realtà sono leggermente più complesse di come esposto ora, ma per ora seguiamo questo modello mentale, che è valido e non molto distante dalla realtà.

Firmare un documento

Ora apriamo un altro argomento, che sembra distaccato dal precedente ma che in realtà, vedremo, lo andrà a completare in modo inaspettato.

Gli algoritmi a chiave asimmetrica permettono di introdurre la firma di un documento: questo è uno dei vantaggi rispetto all’utilizzi degli algoritmi a chiave simmetrica.

Imaginiamo che Bob voglia inviare una mail ad Alice, e si voglia essere sicuri che nessuno modifichi nel tragitto che segue questa il testo del messaggio.

In altri termini l’intento è quello di creare un meccanismo che permetta ad Alice di validare il messaggio ricevuto, in modo tale da essere sicura che il testo sia proprio quello scritto da Bob nel momento in cio lo ha spedito, e cioè che nessuno lo abbia modificato.

Oss.: Questa eventualità che qualcuno nel tragitto seguito da un flusso di comunicazioni tra due entità modifichi i messaggi scambiati prende il nome di attacco man-in-the-middle, che rappresenta una vera e propria ossessione per chi si occupa di sicurezza (il perchè si usa man, e non woman non è dato sapere….).

Oss.: Il protocollo che sottende lo scambio di mail in realtà fa transitare il testo delle mail in chiaro, e teoricamente è abbastanza semplice modificarne il testo.

Oss.: Per uno scambio di dati tra Bob e Alice sarebbe possibile usare usare qualcosa di simile ad Https, ma per questo ambito dimenticatevi per un attimo di Https e affini: il messaggio inviato da Bob è in clear-text, e viene ricevuto da Alice in clear-text. Occorre solo mettere in piedi un meccanismo che permetta di essere sicuri che il messaggio ricevuto da Alice NON sia stato in alcun modo modificato e che corrisponda perfettamente a quanto digitato da Bob.

Usando un algoritmo a chiave asimmetrica è possibile fare qualcosa del genere.

  1. Bob crea il messaggio e, una volta che ha terminato di scrivere il testo, ne calcola il digest usando un algoritmo di hash.
  2. Bob cripta, usando la sua chiave privata, il digest del testo appena ottenuto, e quindi invia il tutto ad Alice, cioè il testo in chiaro + il valore di digest calcolato però criptato con la propria chiave privata.

Per chi non lo sapesse l’hash è un algoritmo che prende in input una stringa, e quindi fornisce in output un’altra stringa (chiamata stringa digest) che è direttamente connessa alla stringa in originaria.

Dal digest è impossibile ricavare la stringa originaria, e teoricamente ad ogni stringa in ingresso dovrebbero corrispondere un diverso digest.

Anche in questo caso esistono diversi algoritmi che permettono di ottenere un hash data una stringa: alcuni esempi famosi sono MD5 e SHA-1.

Se volete fare alcuni test con l’hashing potete usare il sito fileformat.info – Hash Functions (che Vi porgo in linkografia), dove potete specificare in input un testo e quindi ottenere il digest della stessa usando alcuni degli algoritmi di hash tra i più noti.

Un’altra osservazione importante: il valore di digest criptato con la chiave privata di Bob prende il nome di firma del documento.

A questo punto Alice quando riceve il messaggio per essere sicura che è quello originale scritto da Bob può fare le seguenti operazioni.

  1. Calcola l’hash del messaggio in chiaro ricevuto.
  2. Decripta la firma che accompagna il documento usando la chiave pubblica di Bob, ottenendo così l’hash del documento originale così come calcolato da Bob usando il messaggio originale scritto da lui.
  3. Alice ora è in grado di confrontare i due valori digest: se sono uguali ha la certezza che nessuno nel tragitto ha modificato il messaggio.

Oss.: Il secondo punto se ci si pensa è abbastanza critico: infatti occorre essere sicuri che la chiave utilizzata nell’operazione sia proprio quella di Bob. Ne parleremo più diffusamente nella secondo parte.

Un’osservazione importante prima di proseguire: quanto visto in questa parte è one-way.

Cioè Alice è in grado di comprendere se il messaggio ricevuto da Bob è stato manomesso, ma se per caso Alice stessa dovesse scrivere a Bob, quest’ultimo non avrebbe alcun strumento o possibilità di capire se qualcuno ha modificato nel tragitto il messaggio.

Ovviamente la cosa si risolve brillantemente permettendo anche ad Alice di creare una propria coppia di chiavi pubbliche/private, e applicare in modo inverso lo stesso algoritmo appena visto.

Bene, abbiamo messo le basi per comprendere il “favoloso mondo” dei certificati e degli algoritmi a chiave asimmetrica.

Nella prossima puntata esporrò cosa sono le PKI e perchè sono così importanti.

Linkografia

Online RSA Encryption, Decryption And Key Generator Tool
https://www.devglan.com/online-tools/rsa-encryption-decryption

fileformat.info – Hash Functions
https://www.fileformat.info/tool/hash.htm