Non utilizzare un codice a blocchi con ECB per la crittografia simmetrica
(Si applica a AES, 3DES, ...)
Ecco un post e un articolo Microsoft KB molto simile relativo al modo in cui la modalità ECB produce codice non crittografato.
Vedi anche questo post simile da Rook
Messaggio di testo normale:
Lo stesso messaggio crittografato con la modalità ECB (non importa quale cifra usi):
Lo stesso messaggio ESATTO usando la modalità CBC (di nuovo, non importa cosa cifratura che utilizzi):
Il modo sbagliato
stringa statica pubblica Encrypt (string toEncrypt, string key, bool useHashing) { byte [] keyArray = UTF8Encoding.UTF8.GetBytes (chiave); byte [] toEncryptArray = UTF8Encoding.UTF8.GetBytes (toEncrypt); if (useHashing) keyArray = new MD5CryptoServiceProvider (). ComputeHerviceProvider (). ) {Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7}; ICryptoTransform cTransform = tdes.CreateEncryptor (); byte [] resultArray = cTransform.TransformFinalBlock (toEncryptArray, 0, toEncryptArtrray.Length) (resultArray, 0, resultArray.Length);}
L'errore è nella riga seguente
{Key = keyArray, Mode = CipherMode.ECB , Padding = PaddingMode.PKCS7};
La strada giusta
I bravi ragazzi di Microsoft mi hanno inviato il codice seguente per correggere l'articolo della KB collegato sopra. Viene fatto riferimento nel caso n. 111021973179005
Questo codice di esempio utilizza AES per crittografare i dati e la chiave per la crittografia AES è il codice hash generato da SHA256. AES è l'algoritmo Advanced Encryption Standard (AES). L'algoritmo AES si basa su permutazioni e sostituzioni. Le permutazioni sono riorganizzazioni di dati e le sostituzioni sostituiscono un'unità di dati con un'altra. AES esegue permutazioni e sostituzioni utilizzando diverse tecniche. Per maggiori dettagli su AES, fare riferimento all'articolo "Proteggi i tuoi dati con il nuovo standard di crittografia avanzata" su MSDN Magazine su http://msdn.microsoft.com/en-us/magazine/cc164055.aspx.
SHA è l'algoritmo di hash sicuro. SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512) è ora consigliato. Per informazioni più dettagliate sui valori hash in .NET Framework, fare riferimento a http://msdn.microsoft.com/en-us/library/92f9ye3s.aspx#hash_values .
Il valore predefinito della modalità per il funzionamento dell'algoritmo simmetrico per AesCryptoServiceProvider
è CBC. CBC è la modalità Cipher Block Chaining. Introduce feedback. Prima che ogni blocco di testo normale venga crittografato, viene combinato con il testo cifrato del blocco precedente mediante un'operazione OR esclusiva bit per bit. Ciò garantisce che, anche se il testo normale contiene molti blocchi identici, ciascuno di essi verrà crittografato in un diverso blocco di testo cifrato. Il vettore di inizializzazione viene combinato con il primo blocco di testo normale da un'operazione OR esclusivo bit per bit prima che il blocco venga crittografato. Se un singolo bit del blocco di testo cifrato viene alterato, verrà alterato anche il corrispondente blocco di testo normale. Inoltre, un po 'nel blocco successivo, nella stessa posizione dell'originale morso, verrà storpiato. Per informazioni più dettagliate su CipherMode
, fare riferimento a http://msdn.microsoft.com/en-us/library/system.security.cryptography.ciphermode.aspx.
Ecco il codice di esempio.
// Questa funzione viene utilizzata per crittografare i dati con chiave e iv.
byte [] Encrypt (byte [] data, byte [] chiave, byte [] iv) {// Crea un AESCryptoProvider. using (var aesCryptoProvider = new AesCryptoServiceProvider ()) {// Inizializza AESCryptoProvider con chiave e iv. aesCryptoProvider.KeySize = key.Length * 8; aesCryptoProvider.IV = iv; aesCryptoProvider.Key = chiave; // Crea un criptatore da AESCryptoProvider. using (ICryptoTransform encryptor = aesCryptoProvider.CreateEncryptor ()) {// Crea un flusso di memoria per archiviare i dati crittografati. using (MemoryStream stream = new MemoryStream ()) {// Crea un CryptoStream per crittografare i dati. using (CryptoStream cryptoStream = new CryptoStream (stream, encryptor, CryptoStreamMode.Write)) // Crittografa i dati. cryptoStream.Write (data, 0, data.Length); // restituisce i dati crittografati. return stream.ToArray (); }}}} // Questa funzione viene utilizzata per decrittografare i dati con chiave e iv.byte [] Decrypt (byte [] dati, byte [] chiave, byte [] iv) {// Crea un AESCryptoServiceProvider. using (var aesCryptoProvider = new AesCryptoServiceProvider ()) {// Inizializza AESCryptoServiceProvier con key e iv. aesCryptoProvider.KeySize = key.Length * 8; aesCryptoProvider.IV = iv; aesCryptoProvider.Key = chiave; // Crea decryptor da AESCryptoServiceProvider. using (ICryptoTransform decryptor = aesCryptoProvider.CreateDecryptor ()) {// Crea un flusso di memoria che includa i dati crittografati. using (MemoryStream stream = new MemoryStream (data)) {// Crea un CryptoStream per decrittografare i dati crittografati. using (CryptoStream cryptoStream = new CryptoStream (stream, decryptor, CryptoStreamMode.Read)) {// Crea un array di buffer di byte.
byte [] readData = nuovo byte [1024]; int readDataCount = 0; // Crea un flusso di memoria per archiviare i dati decrittografati. using (MemoryStream resultStream = new MemoryStream ()) {do {// Decrypt the data and write the data into readData buffer array. readDataCount = cryptoStream.Read (readData, 0, readData.Length); // Scrive i dati decrittografati in resultStream. resultStream.Write (readData, 0, readDataCount); } // Controlla se sono presenti altri dati crittografati nel flusso. while (readDataCount > 0); // Restituisce i dati decrittografati. return resultStream.ToArray (); }}}}}} // Questa funzione viene utilizzata per generare una chiave binaria valida con codifica UTF8 e algoritmo hash SHA256.byte [] GetKey (chiave stringa) {// Crea classe algoritmo hash SHA256. using (SHA256Managed sha256 = new SHA256Managed ()) // Decodifica la chiave della stringa in binario e calcola il binario hash della chiave. return sha256.ComputeHash (Encoding.UTF8.GetBytes (key));}
Per maggiori dettagli sulle classi nel codice di esempio, fare riferimento ai seguenti link:
· Classe AesCryptoServiceProvider
· Classe SHA256Managed
· Classe CryptoStream
Inoltre, sono disponibili diversi articoli che possono aiutare a ottenere una migliore comprensione della crittografia in .NET Framework, fare riferimento ai collegamenti seguenti:
· Servizi di crittografia
· .NET Framework Cryptography Model
· Una semplice guida alla crittografia
· Crittografia senza Segreti