No. 202

[Il titolo originale tradotto risulterebbe: "Crittografia per il web: polpettoni salati e altri piatti gustosi". Hash è un polpettone di carne macinata tipico degli Stati Uniti, ndt]

Uno dei più potenti strumenti per la sicurezza a disposizione dei web developer è la crittografia, sostanzialmente un processo per cui le informazioni importanti vengono tradotte in rumore casuale, non leggibile se non dove esplicitamente deliberato. Fino a poco tempo fa, molti governi regolavano i software di crittografia in maniera molto rigida. Ma la crittografia è semplicemente matematica applicata ed è stato provato che è impossibile da occultare. Uno sviluppatore web che lavora su un netbook un po' scarso nella sua cantina ha ora accesso a dei sistemi di crittografia che i governi di qualche decennio fa potevano solo sognare.

Si è tentati a credere che una semplice applicazione web non necessiti di sicurezza a livello di quella industriale perché non conterrà alcuna informazione che valga la pena rubare, come i numeri delle carte di credito, ma sfortunatamente, la tendenza delle persone al riutilizzo delle stesse password su diversi sistemi implica che la compromissione di quello più debole tra questi sistemi possa spesso dare accesso agli altri. Nel 2009, come tutti sanno, un hacker ha ottenuto l'accesso ad un numero di sistemi interni a Twitter compromettendo l'account e-mail di un singolo assistente amministrativo.

Proprio come ogni artigiano deve conoscere gli arnesi e i materiali per raggiungere l'eccellenza, così è importante che i web developer comprendano quali tipi di crittografia funzionano in uno specifico contesto, anche se non è necessario comprenderne i dettagli della matematica che vi è coinvolta. La crittografia applicata male non dà alcun beneficio e può anche essere pericoloso perché crea un falso senso di sicurezza.

Ci sono diversi tipi di sistemi crittografici, ma sono tre le categorie che solitamente vengono associate alle applicazioni web.

Funzioni one-way

Non si può partire da una salsiccia e lavorare all'indietro per produrre gli ingredienti base che la compongono. Allo stesso modo, un hash crittografico è progettato per prendere in ingresso dei dati e farli a brandelli, così che quello che esce al termine del processo di crittografia sia irriconoscibile, in maniera irreversibile. Descritto così, non sembra un'operazione particolarmente difficile né utile, ma gli hash ben progettati hanno due proprietà che li rendono sia complessi sia utili.

Primo: un piccolo cambiamento nell'input dovrebbe creare un drastico cambiamento nell'output. In altre parole, cambiare un carattere nei dati sottoposti a hash produrrà un cambiamento molto più grande di un singolo carattere nell'output. Solitamente, gli hash producono un output di lunghezza fissa (e relativamente breve), indipendentemente dalla dimensione dell'input. Questo significa che più input in teoria potrebbero produrre lo stesso risultato, rendendo impossibile sapere quale fosse il dato originale se un “attacker” avesse solo il risultato dello hash con cui lavorare.

Secondo: un hash produce sempre lo stesso output a fronte dello stesso input. L'applicazione più ovvia per gli hash è lo storage delle password. Un'applicazione web non deve per forza conoscere la password dell'utente: deve solo verificare che la persona che richiede l'accesso conosca la password. Se facciamo lo hash delle password allo stesso modo al momento della creazione dell'account e al login, dobbiamo memorizzare e confrontare solo il risultato dell'operazione di hash per sapere se gli originali coincidono. Poi, anche se il database degli utenti viene esposto, l'“attacker” non ha nulla di tremendamente utile con cui lavorare. Perlomeno, questo è il buon senso comune.

In realtà, non è così semplice. Per prima cosa, non tutti gli algoritmi di hashing sono uguali. Ad esempio, l'algoritmo MD5, una volta molto diffuso, è ora noto per essere crittograficamente debole in generale (sebbene si possa ancora usare per le password). In secondo luogo, sappiamo che molte persone scelgono la stessa password comune. Questo implica che se un attacker conosce il valore hash di “123456” prodotto da alcuni algoritmi popolari, potrà facilmente riconoscerlo all'interno di un database. Elenchi di hash pre-calcolati sono molto diffusi e conosciuti nell'industria della sicurezza come rainbow tables.

Per contrastare questa debolezza, si può “salare il polpettone” [hash significa anche polpettone, ndt]. Date le due proprietà dei buoni algoritmi di hash elencate sopra, possiamo semplicemente appendere un po' di dati alla password dell'utente e memorizzare lo hash di quel testo combinato con gli altri dati piuttosto che la password stessa. Questo creerà un risultato completamente differente ma pur sempre verificabile in maniera semplice.

Confrontate quanto segue:

sha1('password')
=> 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8

sha1('x5T1password')
=> e1f9530af9bde38db0eef386c4d22ec2ba10d2fe

In questo esempio, aggiungere quattro caratteri a caso all'inizio della parola fa cambiare il 95% dell'output risultate. L'algoritmo SHA-1, sviluppato dalla US National Security Agency, è attualmente la funzione hash migliore che si abbia a disposizione e gode di un vaso supporto nei più diffusi linguaggi di programmazione.

Cifratura simmetrica

Ovviamente, le funzioni one-way hanno un uso piuttosto ristretto. In molti casi, l'informazione è cifrata solo per assicurare che non possa essere letta al di fuori del contesto desiderato. Ma all'interno del contesto, ad esempio in una console amministrativa, la cifratura deve poter essere reversibile.

Tuttavia, la prima domanda che uno sviluppatore di applicazioni dovrebbe sempre porsi è: “Ho veramente bisogno di raccogliere e salvare questa informazione?” Immagazzinare solo i dati strettamente necessari solitamente contribuisce a migliorare l'esperienza utente, a semplificare lo sviluppo ed è naturalmente più sicura. Dopo tutto, i dati che non esistono non possono essere rubati o utilizzati.

Ma assumendo che le informazioni sensibili siano realmente cruciali per il funzionamento dell'applicazione, dobbiamo prendere in considerazione come gestirli in maniera sicura. La cifratura reversibile si suddivide in due categorie: nella prima, una sola “chiave segreta” viene usata sia per cifrare che per decodificare i dati. Una chiave è una specie di password, ma dal momento che è più probabile che le chiavi vengano usate dai programmi piuttosto che dalle persone, possono (e dovrebbero) essere molto lunghe e totalmente a caso.

Con i moderni algoritmi, la cifratura simmetrica ha il vantaggio di essere estremamente veloce. Il potente algoritmo AES (noto anche come cifrario di Rijndael) è stato progettato specificatamente per la velocità ed è molto ben supportato, con implementazioni sia nei database server che negli application framework. La cifratura e la decifratura dei dati in MySQL, ad esempio, è così semplice:

INSERT INTO people (pet_name) 
  VALUES (AES_ENCRYPT('Schmoopie','my-secret-key'));

SELECT AES_DECRYPT(pet_name, 'my-secret-key') AS pet_name
  FROM people;

Questo non protegge l'informazione dall'esposizione se un utente malintenzionato riesce ad accedere all'applicazione web, dal momento che sa come decifrare i dati. Tuttavia, protegge dall'apertura accidentale in altri contesti, come i files di backup o un attacco al database stesso.

La cifratura simmetrica funziona bene quando abbiamo bisogno solo di accedere all'informazione in un singolo contesto. Tuttavia, tutta la sua forza risiede nella segretezza della chiave, che può assumere i contorni di una sfida quando vogliamo spostare i dati da un posto ad un altro. Se dobbiamo condividere la chiave, specialmente con più destinatari, questa non sarà più segreta.

Cifratura asimmetrica

Per venire incontro a questa necessità, gli algoritmi asimmetrici fanno affidamento su una coppia di chiavi collegate che vengono generate con delle specifiche proprietà. Quando una chiave cifra un pezzo di informazione, solo la chiave corrispondente all'interno della coppia potrà decifrarla. Questo tipo di cifratura viene anche chiamata crittografia a chiave pubblica perché spesso (ma non sempre) una chiave viene resa pubblica, mentre l'altra viene tenuta privata.

La matematica che rende possibile questo accoppiamento è interessante, ma quello che devono capire gli sviluppatori web è quando utilizzarla e che protezione dà. Comunemente, si incontra questa tecnologia nelle connessioni SSL (ora chiamate TLS). Un web server manda la sua chiave pubblica al browser web, che la usa per cifrare i dati che solo il server potrà decifrare. Può anche essere usata per mandare delle e-mail cifrate.

In confronto alle funzioni simmetriche, quelle asimmetriche sono lente e richiedono chiavi che sono molto più lunghe per essere efficaci. Nelle connessioni TLS, il browser ed il server usano solo la crittografia a chiave pubblica per stabilire una chiave simmetrica temporanea che possono usare per cifrare la comunicazione che seguirà.

Comunque, queste funzioni rivestono un ruolo cruciale nell'esperienza web moderna, permettendoci di proteggere i dati in transito tra un'applicazione ed i suoi utenti. La prevalenza di WiFi libero rende tutto ciò un problema molto reale. Su una rete WiFi libera, gli utenti possono mandare qualunque cosa stiano facendo lungo un raggio considerevole a 360°. Senza cifratura, i dati possono essere facilmente osservati da chiunque abbia un laptop. Due incidenti “ad alto profilo” hanno messo in evidenza questo rischio nel 2010: nel primo, Google entrò in conflitto con le autorità garanti della privacy perché aveva accidentalmente raccolto e memorizzato i dati non protetti di traffico WiFi con le sue auto Street View.

Quello che Google ha fatto in maniera accidentale, altri potrebbero farlo di proposito. Più avanti sempre nel 2010, il plugin Firesheep ha ottenuto titoli in prima pagina mostrando quando fosse semplice (e dannoso) intercettare le reti non protette.

 

Come minimo, le applicazioni web dovrebbero richiedere connessioni TLS quando trasmettono le informazioni di login. Usarle per tutto il traffico sarebbe ancora meglio.

Comprendere il rischio

Dal momento che ormai moltissime persone usano i computer, tutte queste tecnologie non potranno che diventare sempre più importanti per gli sviluppatori web. Gli scorsi anni hanno mostrato che il rischio non è teorico. Non è sufficiente dire “La mia applicazione non ha un profilo tanto alto da poter essere un obiettivo”, perché gli attacchi molto spesso sono automatizzati, non guardano gli obiettivi. Allo stesso tempo, dobbiamo comprendere ed educare gli altri riguardo i rischi specifici e come utilizziamo la tecnologia per minimizzarli. Senza tale educazione, i clienti potrebbero considerare un sito o un'applicazione “sicuri” semplicemente perché accettano connessioni HTTPS, non capendo perché non sono in grado di mandare a loro un'e-mail con la password in chiaro.

La sicurezza non sarà mai assoluta, ma se la si usa in maniera appropriata, la moderna crittografia ci fornisce i mezzi per eliminare i rischi maggiori. Sta a noi metterla in campo.

Illustrazioni: Carlo Brigatti

Share/Save/Bookmark
 

Discutiamone

Ti sembra interessante? Scrivi tu il primo commento


Cenni sull'autore

Lyle Mullican

Lyle Mullican è director of engineering in BioIQ. Lo trovate sui soliti social networks. Vive a Rochester, Minnesota, ha due bambini piccoli e saltuariamente riesce a produrre un po' di arte.

Questo sito per poter funzionare utilizza i cookie. Per saperne di più visita la pagina relativa all' INFORMATIVA