Cosa significa "Crittografia"Crittografia deriva da due parole greche "Kruptòs" che significa nascosto, e "graphia" ossia scrittura. La crittografia viene usata ormai da diversi secoli, e con il passare degli anni si è sempre più evoluta molto velocemente per varie esigenze.
E' stata utilizzata spesso in passato per trasmettere messaggi da regioni diverse durante i numerosi conflitti nella storia. Ma anche più recentemente nella seconda guerra mondiale è stata usata pesantemente.
I tedeschi durante la Guerra avevano inventato Enigma un algoritmo simmetrico per trasmettere in modalità protetta i propri messaggi.
Addirittura pare proprio che la sconfitta della Germania nella guerra fu causata dalla scoperta da parte degli Americani e degli Inglesi dei sistemi usati per scambiarsi segretamente dei messaggi.
Ogni qual volta un codice, un algoritmo veniva forzato e violato, un altro ben più potente lo sostituiva e così avanti fino ai giorni nostri, dove la crittografia viene spesso utilizzata per proteggere le transazioni on line e quindi i numeri delle nostre carte di credito.
.NET Framework e CrittografiaUna delle novità importanti riguardanti il .NET Framework è l'aggiunta di un intero namespace dedicato a questo argomento. Il nome del namespace è :
System.Security.Cryptography.
Nello sviluppo del passato la mancanza di un valido supporto alla crittografia è sempre stato uno degli anelli deboli della catena. Ora il peggio sembra passato e anzi, il Framework ci mette a disposzione una serire di classi dedicate a quasi ogni tipo di algoritmo disponibile.
Elenco solo una parte dei vari algoritmi implementati, MD5, DES, 3DES, RSA, SHA1, algoritmi simmetrici e asimmetrici.
L'algoritmo RijndaelIl
http://www.nist.gov/ ">NIST (National Institute of Standards and Technology), è un organismo federale degli Stati Uniti fondato per permettere lo sviluppo e l'evoluzione della tecnologia, un miglioramento della produttività e della vita in genere.
Qualche anno fa il NIST ha lanciato un concorso per vedere se qualcuno riusciva a proporre un algoritmo per crittografare dati più potente di quello precedente, il DES.
Il DES è stato per molti anni l'algoritmo di riferimento dal 1977 al 1998. Ma in quella data il NIST è stato obbligato a cercare un nuovo algoritmo perchè il DES ormai soffriva di alcuni problemi e la sua violabilità diventava sempre più semplice grazie anche alla potenza di calcolo degli elaboratori.
Il concorso pubblico indetto dal NIST si chiamava
A.E.S. Advanced Encryption Standard.
La lista degli algoritmi presentati era molto lunga, dopo una prima scrematura, rimasero solo 4 o 5 algoritmi, alla fine fu scelto quello il Rijndael.
Questo algoritmo è stato creato da Joan Daemen e Vincent Rijmen e fa parte della categoria degli algoritmi simmetrici.
Ciò significa che usa un'unica chiave, in questo caso privata, per crittografare e decrittografare al contrario di quelli asimmetrici che usano due chiavi (pubblica e privata).
Non andremo a spiegare nel dettaglio come funziona il Rijndael perchè è molto complicato ma se volete espandere le vostre conoscenze, potete fare riferimento a questo link:
http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ ">Rijndael Homepage
EsempioPer non dilungarci inutilmente in altri discorsi, veniamo al sodo e presentiamo subito due blocchi di codice, due funzioni comode per effettuare le due operazioni più comuni Codifica e Decodifica.
Diciamo da subito che è necessario definire due chiavi che saranno usate dal nostro algoritmo per crittografare i dati:
private const string chiave= "AxTYQWCvGTFRbgLL" //16 byte
private const string iv = "QWExcfTyUxxLOafO"; //16 byte
La prima è la nostra chiave ufficiale, che dovrà conoscere solo il destinatario del nostro messaggio.
La seconda invece
IV sta per
Initialization Vector o Vettore di Inizializzazione.
Di solito per crittografare si usa la chiave ufficiale e il risultato della codifica dei byte precedenti.
Quando si inizia da una stringa è chiaro che prima dei primi 8 byte non c'è niente. Quindi il vettore di inizalizzazione serve proprio a questo, per fornire una base di partenza all'algoritmo.
Chiave e vettore di inizalizzazione hanno la stessa dimensione 16 byte.
Vi ricordo che alcune proprietà e metodi (come IV, Key, ecc.) della classe Rijndael vengono ereditati dalla classe Madre
SymmetricAlgorithm così come altre classi di algortimi appartenenti agli algoritmi simmetrici.
Dentro la classe madre ci sono anche due metodi GenerateIV e GenerateKey per creare automaticamente ed in modo casuale le due chiavi enunciate poco fa.
Ecco qui la funzione per la codifica:
public string Encode(string S)
{
RijndaelManaged rjm = new RijndaelManaged();
rjm.KeySize = 128;
rjm.BlockSize = 128;
rjm.Key = ASCIIEncoding.ASCII.GetBytes(chiave);
rjm.IV = ASCIIEncoding.ASCII.GetBytes(iv);
Byte[] input = Encoding.UTF8.GetBytes(S);
Byte[] output = rjm.CreateEncryptor().TransformFinalBlock(input, 0,
input.Length);
return Convert.ToBase64String(output);
}
e quella per la decodifica:
public string Decode(string S)
{
RijndaelManaged rjm = new RijndaelManaged();
rjm.KeySize = 128;
rjm.BlockSize = 128;
rjm.Key = ASCIIEncoding.ASCII.GetBytes(chiave);
rjm.IV = ASCIIEncoding.ASCII.GetBytes(iv);
try
{
Byte[] input = Convert.FromBase64String(S);
Byte[] output = rjm.CreateDecryptor().TransformFinalBlock(input, 0,
input.Length);
return Encoding.UTF8.GetString(output);
}
catch
{
return S;
}
}
In queste due funzioni c'è molto poco da spiegare, sono abbastanza chiare.
C'è l'inizializzazione della classe RijndaelManaged, c'è la definizione della dimensione della chiave in bit cioè 128 ossia uguale a 16 byte, come abbiamo definito sopra.
Abbiamo la definizione del BlockSize cioè l'unità minima da crittografare anch'essa di 128 bit, vengono assegnate alle due proprietà Key e IV le due chiavi definite sopra convertite in un array di byte, viene convertita la stringa da crittografare in input in formato Base64 e viene chiamato il metodo
TransformFinalBlock per Codificare o Decodificare, in base alla funzione chiamata, la nostra stringa data in input alla funzione.