Nel campo IT relativo alla Sicurezza spesso si affrontano discorsi composti di termini, non spesso, propriamente conosciuti.
Nel prossimi 3 post passeremo in rassegna i maggiori termini tendando di fornire una descrizione accurata di ogniuno di essi. Per la precisione parleremo di
- Plaintext
- Ciphertext
- Hashes
- Keys
- Symmetric Algorithms
- Asymmetric Algorithms
- Comparazione tipi di Chiavi
- Generazione di numeri Random
Plaintext - Ciphertext
Plaintext (testo semplice) descrive lo stato di un messaggio che può essere letto facilmente da tutti e tutto. Questo può essere un semplice file di testo fino ad arrivare ad un eseguibile. Per "alterare" una informazione di questo tipo si ha la necessità di utilizzare un algoritmo di encrypting per cambiare lo stato da Plaintext a Ciphertext (testo cifrato.) Effettuando questa operazione, si ha l'augurio che il Ciphertext non sia riconvertibile a Plaintext (testo semplice) facilmente. Per riconvertirlo sarà infatti necessario utilizzare un algoritmo di decrypting.
Il messaggio Plaintext (Messaggio testo semplice) è definito come M, ed il Ciphertext (Messaggio Cifrato) è definito come C. In entrambe le situazioni, una funzione E (Encryption) o D (Decryption) opera in M o C, per riprodurre l'output desiderato.
Hashes
Hashes (Valori di Hash) sono usati per creare un unico, compatto valore per un ben specificato messaggio. Il messaggio (in linguaggio tecnico security definito pre-image), è usato come input per ricevere l'algoritmo di hash finale. Il valore di output del Hash utilizzato è di tipologia Fixed-Size per ogni tipo di valore input (pre-image). La figura che segue ne dimostra il funzionamento
H(P) sta per l'algoritmo di hash che opera nel messaggio input (pre-image). In questo caso, H produrrà sempre un valore di hash avente dimensioni di 4 bytes . La struttura del valore di output (hash value) non è importante: l'unica cosa realmente importante è che il valore di hash corrispondente è unico per il valore di input proposto (pre-image). Si può quindi definire che l'utilizzo degli Hashes è realmente utile quando i messaggi necessitano di operazioni di encrypt. Le funzioni di Hash sono usualmente molto veloci e sopratutto asimmetriche. Questo significa che è possibile prendere un pre-image e creare un valore di hash, ma non è possibile effettuare l'operazione inversa (almeno non facilmente).
Un altra operazione in cui spesso gli Hashes sono maggiormente presenti è lo storing (archiviazione) delle password all'interno di database. Invece di "archiviare" la password in formato Plaintext, l'applicazione crea ed archivia un hash del pre-image al suo interno. La maggior parte delle volte l'utente finale non ha la necessità di essere a conoscenza del fatto che questa operazione è stata eseguita. Nel caso di futuri login, l'applicazione farà la comparazione con i valori di hash e autorizzerà l'utente all'accesso alla risorsa richiesta. I vantaggi nell'applicare questa operazione sono molteplici. Basti solo pensare il caso in cui le "mura" (precedentemente descritti nei primi post relativi alla .NET Security) del nostro database cadano. In questo caso l'utente maleintenzionato avrà in mano solo una serie di valori di hash con cui non potrà effettuare alcuna operazione. Analiziamo insieme la figura che segue (si supponga che "myPassword" sia la password dell'utente finale che richiede l'accesso ad una determinata risorsa.
Parlando ad un livello molto generale si può tranquillamente affermare che creare un hash value a partire da una pre-image è decisamente facile. Tuttavia, trovare la pre-image corrispondente al hash value è, a livelli statistici, quasi impossibile. Naturalmente applicando la regola del "Mai dire Mai", una piccola possibilità di recupero pre-image è possibile attraverso un attacco di tipo Dictionary.
Nel caso si volgia aggiungere una contromisura alla tecnica del Dictionary Attack è necessario operarare sulla falsa linea di quanto descritto fin ora. Partendo da un messaggio Pre-Image aggiungiamo al hash dei valori che non hanno alcun riferimento logico con il pre-Image. Perchè viene applicata questa tecnica che può sembrare in qualche modo "preistorica"?. Semplice..
Nel caso in cui l'integrità del nostro database venga compromessa, l'utente maleintenzionato ha un unico modo per tentare di recuperare qualche password. Per prima cosa procede a mettersi a disposizione un Dizionario contenente numerosi vocaboli (possibile password), in seguito procede alla computazione del Hash a partire da i valori in esso presenti. Per ogni valore di Hash ottenuto, effettua un confronto con i valori contenuti nel database. In caso di Match positivo ha trovato la password e le nostre difese sono state definitivamente violate. L'aggiunta di questi valori casuali (definiti salt) rendono la vita decisamente difficile all'utente di turno. Non solo ora dovrà avere un buon dizionario ed una macchina abbastanza potente da elaborare tutte le computazioni.. ora dovrà anche aggiungere tutte le possibili combinazioni di testo al hash risultante dalle sue operazioni. Il tutto si traduce in un più chiaro "Molto difficilmente riuscirà a bucare la nostra applicazione). La figura che segue mostra lo schema dell'impiego dei salt.
Nel prossimo post, ora che si conosce il funzionamento degli Hash, descriveremo il funzionamento delle Keys (chiavi) negli algoritmi di encryption.