Crittografia

Creazione di una libreria di crittografia

In questa pagina
ObiettiviObiettivi
Ambito di applicazioneAmbito di applicazione
Utilizzo del moduloUtilizzo del modulo
RiepilogoRiepilogo
Creazione di una libreria di classi Visual C#Creazione di una libreria di classi Visual C#
Creazione di un'applicazione console di provaCreazione di un'applicazione console di prova
Altre risorseAltre risorse

Obiettivi

Il modulo consente di:

Creare una libreria generica di crittografia per crittografare e decrittografare i dati in DES (Digital Encryption Standard), Tripe DES, Rijndeal o RC2.

Utilizzare la libreria di crittografia dalle applicazioni.

Ambito di applicazione

Le informazioni contenute in questo modulo sono valide per i seguenti prodotti e tecnologie:

Microsoft Windows® XP o Windows 2000 Server con Service Pack 3 e sistemi operativi successivi

.NET Framework versione 1.0 con Service Pack 2 e versioni successive

Microsoft Visual C#® .NET

Utilizzo del modulo

In questo modulo vengono descritti in dettaglio i passaggi e il codice necessari per creare una libreria generica di crittografia utilizzando Visual C#. Per trarre il massimo vantaggio dal modulo:

È necessario aver acquisito esperienza nell'utilizzo di Visual C# .NET e Microsoft Visual Studio® .NET.

Leggere "Procedura - Archiviazione di una stringa di connessione crittografata nel Registro di sistema" per un esempio di come utilizzare la libreria descritta in questo modulo.

Riepilogo

Microsoft® .NET Framework fornisce supporto per una vasta gamma di algoritmi simmetrici di crittografia ampiamente utilizzati. Le classi che rappresentano questi algoritmi sono ben strutturate e utilizzabili allo stesso modo. Pertanto, anziché scrivere il codice in ogni applicazione per la crittografia e la decrittografia dei dati riservati, è possibile creare con facilità una libreria riutilizzabile che consente di crittografare e decrittografare i dati mediante qualsiasi algoritmo simmetrico di crittografia disponibile. In questo modulo viene descritto come creare una simile libreria.

Creazione di una libreria di classi Visual C#

Questa procedura consente di creare una libreria di classi Visual C# che fornirà le funzionalità di crittografia e decrittografia.

Per creare una libreria di classi Visual C#

1.

Avviare Visual Studio .NET e creare un nuovo progetto Libreria di classi Visual C# denominato Encryption.

2.

Utilizzare Esplora soluzioni per rinominare class1.cs come EncryptTransformer.cs.

3.

In EncryptTransformer.cs rinominare Class1 come EncryptTransformer.

4.

Modificare l'ambito della classe da public a internal.

internal class EncryptTransformer 

5.

Aggiungere la seguente istruzione using all'inizio del file.

using System.Security.Cryptography; 

6.

Aggiungere il tipo enumerato riportato di seguito all'interno dello spazio dei nomi Encryption.

public enum EncryptionAlgorithm {Des = 1, Rc2, Rijndael, TripleDes}; 

7.

Aggiungere le variabili membro private riportate di seguito alla classe EncryptTransformer.

private EncryptionAlgorithm algorithmID; 
private byte[] initVec; 
private byte[] encKey; 

8.

Sostituire il costruttore predefinito con il seguente:

internal EncryptTransformer(EncryptionAlgorithm algId) 
{ 
  //Save the algorithm being used. 
  algorithmID = algId; 
} 

9.

Aggiungere alla classe il seguente metodo:

internal ICryptoTransform GetCryptoServiceProvider(byte[] bytesKey) 
{ 
  // Pick the provider. 
  switch (algorithmID) 
  { 
    case EncryptionAlgorithm.Des: 
    { 
      DES des = new DESCryptoServiceProvider(); 
      des.Mode = CipherMode.CBC; 
      // See if a key was provided 
      if (null == bytesKey) 
      { 
        encKey = des.Key; 
      } 
      else 
      { 
        des.Key = bytesKey; 
        encKey = des.Key; 
      } 
      // See if the client provided an initialization vector 
      if (null == initVec) 
      { // Have the algorithm create one 
        initVec = des.IV; 
      } 
      else 
      { //No, give it to the algorithm 
        des.IV = initVec; 
      } 
      return des.CreateEncryptor(); 
    } 
    case EncryptionAlgorithm.TripleDes: 
    { 
      TripleDES des3 = new TripleDESCryptoServiceProvider(); 
      des3.Mode = CipherMode.CBC; 
      // See if a key was provided 
      if (null == bytesKey) 
      { 
        encKey = des3.Key; 
      } 
      else 
      { 
        des3.Key = bytesKey; 
        encKey = des3.Key; 
      } 
      // See if the client provided an IV 
      if (null == initVec) 
      { //Yes, have the alg create one 
        initVec = des3.IV; 
      } 
      else 
      { //No, give it to the alg. 
        des3.IV = initVec; 
      } 
      return des3.CreateEncryptor(); 
    } 
    case EncryptionAlgorithm.Rc2: 
    { 
      RC2 rc2 = new RC2CryptoServiceProvider(); 
      rc2.Mode = CipherMode.CBC; 
      // Test to see if a key was provided 
      if (null == bytesKey) 
      { 
        encKey = rc2.Key; 
      } 
      else 
      { 
        rc2.Key = bytesKey; 
        encKey = rc2.Key; 
      } 
      // See if the client provided an IV 
      if (null == initVec) 
      { //Yes, have the alg create one 
        initVec = rc2.IV; 
      } 
      else 
      { //No, give it to the alg. 
        rc2.IV = initVec; 
      } 
      return rc2.CreateEncryptor(); 
    } 
    case EncryptionAlgorithm.Rijndael: 
    { 
      Rijndael rijndael = new RijndaelManaged(); 
      rijndael.Mode = CipherMode.CBC; 
      // Test to see if a key was provided 
      if(null == bytesKey) 
      { 
        encKey = rijndael.Key; 
      } 
      else 
      { 
        rijndael.Key = bytesKey; 
        encKey = rijndael.Key; 
      } 
      // See if the client provided an IV 
      if(null == initVec) 
      { //Yes, have the alg create one 
        initVec = rijndael.IV; 
      } 
      else 
      { //No, give it to the alg. 
        rijndael.IV = initVec; 
      } 
      return rijndael.CreateEncryptor(); 
    }  
    default: 
    { 
      throw new CryptographicException("Algorithm ID '" + algorithmID +  
                                       "' not supported."); 
    } 
  } 
} 

10.

Aggiungere alla classe le seguenti proprietà:

internal byte[] IV 
{ 
  get{return initVec;} 
  set{initVec = value;} 
} 
internal byte[] Key 
{ 
  get{return encKey;} 
} 

11.

Aggiungere una nuova classe denominata DecryptTransformer al progetto.

12.

Aggiungere la seguente istruzione using all'inizio del file DecryptTransformer.cs.

using System.Security.Cryptography; 

13.

Modificare l'ambito della classe da public a internal.

14.

Sostituire il costruttore predefinito con il seguente:

internal DecryptTransformer(EncryptionAlgorithm deCryptId) 
{ 
  algorithmID = deCryptId; 
} 

15.

Aggiungere alla classe le seguenti variabili private:

private EncryptionAlgorithm algorithmID; 
private byte[] initVec; 

16.

Aggiungere alla classe il seguente metodo:

internal ICryptoTransform GetCryptoServiceProvider(byte[] bytesKey) 
{ 
  // Pick the provider. 
  switch (algorithmID) 
  { 
    case EncryptionAlgorithm.Des: 
    { 
      DES des = new DESCryptoServiceProvider(); 
      des.Mode = CipherMode.CBC; 
      des.Key = bytesKey; 
      des.IV = initVec; 
      return des.CreateDecryptor(); 
    } 
    case EncryptionAlgorithm.TripleDes: 
    { 
      TripleDES des3 = new TripleDESCryptoServiceProvider(); 
      des3.Mode = CipherMode.CBC; 
      return des3.CreateDecryptor(bytesKey, initVec); 
    } 
    case EncryptionAlgorithm.Rc2: 
    { 
      RC2 rc2 = new RC2CryptoServiceProvider(); 
      rc2.Mode = CipherMode.CBC; 
      return rc2.CreateDecryptor(bytesKey, initVec); 
    } 
    case EncryptionAlgorithm.Rijndael: 
    { 
      Rijndael rijndael = new RijndaelManaged(); 
      rijndael.Mode = CipherMode.CBC; 
      return rijndael.CreateDecryptor(bytesKey, initVec); 
    }  
    default: 
    { 
      throw new CryptographicException("Algorithm ID '" + algorithmID +  
                                       "' not supported."); 
    } 
  } 
} //end GetCryptoServiceProvider 

17.

Aggiungere alla classe la seguente proprietà:

internal byte[] IV 
{ 
  set{initVec = value;} 
} 

18.

Aggiungere una nuova classe denominata Encryptor al progetto.

19.

Aggiungere le seguenti istruzioni using all'inizio del file Encryptor.cs.

using System.Security.Cryptography; 
using System.IO; 

20.

Sostituire il costruttore predefinito con il seguente:

public Encryptor(EncryptionAlgorithm algId) 
{ 
  transformer = new EncryptTransformer(algId); 
} 

21.

Aggiungere alla classe le seguenti variabili membro private:

private EncryptTransformer transformer; 
private byte[] initVec; 
private byte[] encKey; 

22.

Aggiungere alla classe il seguente metodo Encrypt:

public byte[] Encrypt(byte[] bytesData, byte[] bytesKey) 
{ 
  //Set up the stream that will hold the encrypted data. 
  MemoryStream memStreamEncryptedData = new MemoryStream(); 
  transformer.IV = initVec; 
  ICryptoTransform transform = transformer.GetCryptoServiceProvider 
  (bytesKey); 
  CryptoStream encStream = new CryptoStream(memStreamEncryptedData,  
                                            transform,  
                                            CryptoStreamMode.Write); 
  try 
  { 
    //Encrypt the data, write it to the memory stream. 
    encStream.Write(bytesData, 0, bytesData.Length); 
  } 
  catch(Exception ex) 
  { 
    throw new Exception("Error while writing encrypted data to the  
    stream: \n"  
                        + ex.Message); 
  } 
  //Set the IV and key for the client to retrieve 
  encKey = transformer.Key; 
  initVec = transformer.IV; 
  encStream.FlushFinalBlock(); 
  encStream.Close(); 
  //Send the data back. 
  return memStreamEncryptedData.ToArray(); 
}//end Encrypt 

23.

Aggiungere alla classe le seguenti proprietà:

public byte[] IV 
{ 
  get{return initVec;} 
  set{initVec = value;} 
} 
public byte[] Key 
{ 
  get{return encKey;} 
} 

24.

Aggiungere una nuova classe denominata Decryptor al progetto.

25.

Aggiungere le seguenti istruzioni using all'inizio del file Decryptor.cs:

using System.Security.Cryptography; 
using System.IO; 

26.

Sostituire il costruttore predefinito con il seguente:

public Decryptor(EncryptionAlgorithm algId) 
{ 
  transformer = new DecryptTransformer(algId); 
} 

27.

Aggiungere alla classe le seguenti variabili membro private:

private DecryptTransformer transformer; 
private byte[] initVec; 

28.

Aggiungere alla classe il seguente metodo Decrypt:

public byte[] Decrypt(byte[] bytesData, byte[] bytesKey) 
{ 
  //Set up the memory stream for the decrypted data. 
  MemoryStream memStreamDecryptedData = new MemoryStream(); 
  //Pass in the initialization vector. 
  transformer.IV = initVec; 
  ICryptoTransform transform = transformer.GetCryptoServiceProvider 
  (bytesKey); 
  CryptoStream decStream = new CryptoStream(memStreamDecryptedData,  
                                            transform,  
                                            CryptoStreamMode.Write); 
  try 
  { 
    decStream.Write(bytesData, 0, bytesData.Length); 
  } 
  catch(Exception ex) 
  { 
    throw new Exception("Error while writing encrypted data to the  
    stream: \n"  
                        + ex.Message); 
  } 
  decStream.FlushFinalBlock(); 
  decStream.Close(); 
  // Send the data back. 
  return memStreamDecryptedData.ToArray(); 
} //end Decrypt 

29.

Aggiungere alla classe la seguente proprietà:

public byte[] IV 
{ 
  set{initVec = value;} 
} 

30.

Scegliere Genera soluzione dal menu Genera.

Creazione di un'applicazione console di prova

Questa procedura consente di creare una semplice applicazione console di prova per verificare le funzionalità di crittografia e decrittografia.

Per creare un'applicazione console di prova

1.

Aggiungere alla soluzione corrente una nuova applicazione console Visual C# denominata EncryptionTester.

2.

In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto EncryptionTester, quindi scegliere Imposta come progetto di avvio.

3.

Utilizzare Esplora soluzioni per rinominare class1.cs come EncryptionTest.cs.

4.

In EncryptionTest.cs rinominare Class1 come EncryptionTest.

5.

Aggiungere un riferimento al progetto nel progetto Encryption.

6.

Aggiungere le seguenti istruzioni using all'inizio del file EncryptionTest.cs:

using System.Text; 
using Encryption; 

7.

Aggiungere al metodo Main il seguente codice:

// Set the required algorithm 
EncryptionAlgorithm algorithm = EncryptionAlgorithm.Des; 
// Init variables. 
byte[] IV = null; 
byte[] cipherText = null; 
byte[] key = null; 
try 
{ //Try to encrypt. 
  //Create the encryptor. 
  Encryptor enc = new Encryptor(EncryptionAlgorithm.Des); 
  byte[] plainText = Encoding.ASCII.GetBytes("Test String"); 
  if ((EncryptionAlgorithm.TripleDes == algorithm) ||  
      (EncryptionAlgorithm.Rijndael == algorithm)) 
  { //3Des only work with a 16 or 24 byte key. 
    key = Encoding.ASCII.GetBytes("password12345678"); 
    if (EncryptionAlgorithm.Rijndael == algorithm) 
    { // Must be 16 bytes for Rijndael. 
      IV = Encoding.ASCII.GetBytes("init vec is big."); 
    } 
    else 
    { 
      IV = Encoding.ASCII.GetBytes("init vec"); 
    } 
  } 
  else 
  { //Des only works with an 8 byte key. The others uses variable  
  length  
  keys. 
    //Set the key to null to have a new one generated. 
    key = Encoding.ASCII.GetBytes("password"); 
    IV = Encoding.ASCII.GetBytes("init vec"); 
  } 
  // Uncomment the next lines to have the key or IV generated for you. 
  // key = null; 
  // IV = null; 
  enc.IV = IV; 
  // Perform the encryption. 
  cipherText = enc.Encrypt(plainText, key); 
  // Retrieve the intialization vector and key. You will need it  
  // for decryption. 
  IV = enc.IV; 
  key = enc.Key; 
  // Look at your cipher text and initialization vector. 
  Console.WriteLine("          Cipher text: " +  
                    Convert.ToBase64String(cipherText)); 
  Console.WriteLine("Initialization vector: " + Convert.ToBase64 
  String(IV)); 
  Console.WriteLine("                  Key: " + Convert.ToBase64 
  String(key)); 
} 
catch(Exception ex) 
{ 
  Console.WriteLine("Exception encrypting. " + ex.Message); 
  return; 
} 
try 
{ //Try to decrypt. 
  //Set up your decryption, give it the algorithm and initialization  
  vector. 
  Decryptor dec = new Decryptor(algorithm); 
  dec.IV = IV; 
  // Go ahead and decrypt. 
  byte[] plainText = dec.Decrypt(cipherText, key); 
  // Look at your plain text. 
  Console.WriteLine("           Plain text: " +  
                    Encoding.ASCII.GetString(plainText)); 
} 
catch(Exception ex) 
{ 
  Console.WriteLine("Exception decrypting. " + ex.Message); 
  return; 
} 

8.

Scegliere Genera soluzione dal menu Genera.

9.

Eseguire l'applicazione di prova per verificare il funzionamento delle classi Encryptor e Decryptor.

Altre risorse

Per ulteriori informazioni, vedere "Procedura - Archiviazione di una stringa di connessione crittografata nel Registro di sistema"


**
In questo articolo
**