Procedura dettagliata: creazione di un'applicazione di crittografiaWalkthrough: Creating a Cryptographic Application

Questa procedura dettagliata illustra come crittografare e decrittografare il contenuto.This walkthrough demonstrates how to encrypt and decrypt content. Gli esempi di codice sono progettati per un'applicazione Windows Forms.The code examples are designed for a Windows Forms application. Questa applicazione non illustra situazioni del mondo reale, come l'utilizzo di smart card.This application does not demonstrate real world scenarios, such as using smart cards. Al contrario illustra gli aspetti fondamentali della crittografia e decrittografia.Instead, it demonstrates the fundamentals of encryption and decryption.

Questa procedura dettagliata usa le linee guida seguenti per la crittografia:This walkthrough uses the following guidelines for encryption:

  • Usare la classe RijndaelManaged, un algoritmo simmetrico, per crittografare e decrittografare dati mediante le proprietà Key e IV generate automaticamente.Use the RijndaelManaged class, a symmetric algorithm, to encrypt and decrypt data by using its automatically generated Key and IV.

  • Usare RSACryptoServiceProvider, un algoritmo generato automaticamente, per crittografare e decrittografare la chiave di dati crittografati da RijndaelManaged.Use the RSACryptoServiceProvider, an asymmetric algorithm, to encrypt and decrypt the key to the data encrypted by RijndaelManaged. Gli algoritmi asimmetrici sono ideali per più piccole quantità di dati, come ad esempio una chiave.Asymmetric algorithms are best used for smaller amounts of data, such as a key.

    Nota

    Se si vogliono proteggere dati sul computer anziché scambiare contenuto crittografato con altri utenti, è possibile usare le classi ProtectedData o ProtectedMemory.If you want to protect data on your computer instead of exchanging encrypted content with other people, consider using the ProtectedData or ProtectedMemory classes.

Nella seguente tabella sono riepilogate le attività crittografate in questo argomento.The following table summarizes the cryptographic tasks in this topic.

AttivitàTask DescrizioneDescription
Creazione di un'applicazione Windows FormCreating a Windows Forms application Elenca i controlli necessari per l'esecuzione dell'applicazione.Lists the controls that are required to run the application.
Dichiarazione di oggetti globaliDeclaring global objects Dichiara le variabili del percorso stringa, CspParameters e RSACryptoServiceProvider per avere il contenuto globale della classe Form.Declares string path variables, the CspParameters, and the RSACryptoServiceProvider to have global context of the Form class.
Creazione di una chiave asimmetricaCreating an asymmetric key Crea una coppia chiave-valore pubblica e privata asimmetrica e le assegna un nome del contenitore di chiavi.Creates an asymmetric public and private key value pair and assigns it a key container name.
Crittografia di un fileEncrypting a file Visualizza una finestra di dialogo per selezionare un file per la crittografia e lo crittografa.Displays a dialog box to select a file for encryption and encrypts the file.
Decrittografia di un fileDecrypting a file Visualizza una finestra di dialogo per selezionare un file crittografato per la decrittografia e lo decrittografa.Displays a dialog box to select an encrypted file for decryption and decrypts the file.
Recupero di una chiave privataGetting a private key Ottiene una coppia di chiavi completa usando il nome del contenitore di chiavi.Gets the full key pair using the key container name.
Esportazione di una chiave pubblicaExporting a public key Salva la chiave in un file XML con solo parametri pubblici.Saves the key to an XML file with only public parameters.
Importazione di una chiave pubblicaImporting a public key Carica la chiave da un file XML in un contenitore di chiavi.Loads the key from an XML file into the key container.
Test dell'applicazioneTesting the application Elenca le procedure per il test di questa applicazione.Lists procedures for testing this application.

PrerequisitiPrerequisites

Per completare la procedura dettagliata, è necessario disporre dei componenti seguenti:You need the following components to complete this walkthrough:

Creazione di un'applicazione Windows FormCreating a Windows Forms Application

La maggior parte degli esempi di codice in questa procedura dettagliata sono progettati per essere gestori di eventi per i controlli pulsante.Most of the code examples in this walkthrough are designed to be event handlers for button controls. Nella tabella seguente sono elencati i controlli necessari per l'applicazione di esempio e i relativi nomi richiesti per la corrispondenza con gli esempi di codice.The following table lists the controls required for the sample application and their required names to match the code examples.

ControlControl nomeName Proprietà di testo (in base alle necessità)Text property (as needed)
Button buttonEncryptFile Crittografa un fileEncrypt File
Button buttonDecryptFile Decrittografa un fileDecrypt File
Button buttonCreateAsmKeys Crea chiaviCreate Keys
Button buttonExportPublicKey Esporta una chiave pubblicaExport Public Key
Button buttonImportPublicKey Importa una chiave pubblicaImport Public Key
Button buttonGetPrivateKey Ottiene una chiave privataGet Private Key
Label label1
OpenFileDialog openFileDialog1
OpenFileDialog openFileDialog2

Fare doppio clic sul pulsante nella finestra di progettazione di Visual Studio per creare i relativi gestori eventi.Double-click the buttons in the Visual Studio designer to create their event handlers.

Dichiarazione di oggetti globaliDeclaring Global Objects

Aggiungere il seguente codice al costruttore del form:Add the following code to the Form's constructor. Modificare le variabili di stringa per l'ambiente e le preferenze.Edit the string variables for your environment and preferences.

// Declare CspParmeters and RsaCryptoServiceProvider
// objects with global scope of your Form class.
CspParameters cspp = new CspParameters();
RSACryptoServiceProvider rsa;

// Path variables for source, encryption, and
// decryption folders. Must end with a backslash.
const string EncrFolder = @"c:\Encrypt\";
const string DecrFolder = @"c:\Decrypt\";
const string SrcFolder = @"c:\docs\";

// Public key file
const string PubKeyFile = @"c:\encrypt\rsaPublicKey.txt";

// Key container name for
// private/public key value pair.
const string keyName = "Key01";
' Declare CspParmeters and RsaCryptoServiceProvider 
' objects with global scope of your Form class.
Dim cspp As CspParameters = New System.Security.Cryptography.CspParameters
Dim rsa As RSACryptoServiceProvider

' Path variables for source, encryption, and
' decryption folders. Must end with a backslash.
Dim EncrFolder As String = "c:\Encrypt\"
Dim DecrFolder As String = "c:\Decrypt\"
Dim SrcFolder As String = "c:\docs\"

' Public key file
Dim PubKeyFile As String = "c:\encrypt\rsaPublicKey.txt"

' Key container name for
' private/public key value pair.
Dim keyName As String = "Key01"

Creazione di una chiave asimmetricaCreating an Asymmetric Key

Questa attività crea una chiave asimmetrica che crittografa e decrittografa la chiave RijndaelManaged.This task creates an asymmetric key that encrypts and decrypts the RijndaelManaged key. Questa chiave era usata per crittografare il contenuto e visualizza il nome del contenitore di chiavi nel controllo etichetta.This key was used to encrypt the content and it displays the key container name on the label control.

Aggiungere il codice seguente come gestore eventi Click per il pulsante Create Keys (buttonCreateAsmKeys_Click).Add the following code as the Click event handler for the Create Keys button (buttonCreateAsmKeys_Click).

private void buttonCreateAsmKeys_Click(object sender, System.EventArgs e)
{
    // Stores a key pair in the key container.
    cspp.KeyContainerName = keyName;
    rsa = new RSACryptoServiceProvider(cspp);
    rsa.PersistKeyInCsp = true;
    if (rsa.PublicOnly == true)
       label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only";
    else
       label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair";

}
Private Sub buttonCreateAsmKeys_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonCreateAsmKeys.Click
    ' Stores a key pair in the key container.
    cspp.KeyContainerName = keyName
    rsa = New RSACryptoServiceProvider(cspp)
    rsa.PersistKeyInCsp = True

    If rsa.PublicOnly = True Then
        Label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only"
    Else
        Label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair"
    End If

End Sub

Crittografia di un fileEncrypting a File

Questa attività vengono usati due metodi: il metodo del gestore eventi per il Encrypt File pulsante (buttonEncryptFile_Click) e EncryptFile metodo.This task involves two methods: the event handler method for the Encrypt File button (buttonEncryptFile_Click) and the EncryptFile method. Il primo metodo visualizza una finestra di dialogo per la selezione di un file e passa il nome file al secondo metodo, che esegue la crittografia.The first method displays a dialog box for selecting a file and passes the file name to the second method, which performs the encryption.

Il contenuto, la chiave e il vettore di inizializzazione (IV) crittografati vengono tutti salvati in un FileStream, a cui si fa riferimento come pacchetto di crittografia.The encrypted content, key, and IV are all saved to one FileStream, which is referred to as the encryption package.

Il metodo EncryptFile esegue le operazioni seguenti:The EncryptFile method does the following:

  1. Crea un algoritmo simmetrico RijndaelManaged per crittografare il contenuto.Creates a RijndaelManaged symmetric algorithm to encrypt the content.

  2. Crea un oggetto RSACryptoServiceProvider per crittografare la chiave RijndaelManaged.Creates an RSACryptoServiceProvider object to encrypt the RijndaelManaged key.

  3. Usa un oggetto CryptoStream per leggere e crittografare FileStream del file di origine, in blocchi di byte, in un oggetto FileStream di destinazione per il file crittografato.Uses a CryptoStream object to read and encrypt the FileStream of the source file, in blocks of bytes, into a destination FileStream object for the encrypted file.

  4. Determina le lunghezze della chiave e del vettore di inizializzazione (IV) crittografati e crea matrici di byte dei valori delle relative lunghezze.Determines the lengths of the encrypted key and IV, and creates byte arrays of their length values.

  5. Scrive la chiave, il vettore di inizializzazione (IV) e i valori delle relative lunghezze nel pacchetto di crittografia.Writes the Key, IV, and their length values to the encrypted package.

Il pacchetto di crittografia usa il seguente formato:The encryption package uses the following format:

  • Lunghezza chiave, byte 0 - 3Key length, bytes 0 - 3

  • Lunghezza vettore di inizializzazione, byte 4 - 7IV length, bytes 4 - 7

  • Chiave crittografataEncrypted key

  • Vettore di inizializzazione (IV)IV

  • Testo crittografatoCipher text

È possibile usare le lunghezze della chiave e del vettore di inizializzazione (IV) per determinare i punti iniziali e lunghezze di tutte le parti del pacchetto di crittografia, che quindi può essere usato per decrittografare il file.You can use the lengths of the key and IV to determine the starting points and lengths of all parts of the encryption package, which can then be used to decrypt the file.

Aggiungere il codice seguente come gestore eventi Click per il pulsante Encrypt File (buttonEncryptFile_Click).Add the following code as the Click event handler for the Encrypt File button (buttonEncryptFile_Click).

private void buttonEncryptFile_Click(object sender, System.EventArgs e)
{
    if (rsa == null)
        MessageBox.Show("Key not set.");
    else
    {

        // Display a dialog box to select a file to encrypt.
        openFileDialog1.InitialDirectory = SrcFolder;
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            string fName = openFileDialog1.FileName;
            if (fName != null)
            {
                FileInfo fInfo = new FileInfo(fName);
                // Pass the file name without the path.
                string name = fInfo.FullName;
                EncryptFile(name);
            }
        }
    }
}
Private Sub buttonEncryptFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonEncryptFile.Click
    If rsa Is Nothing Then
        MsgBox("Key not set.")
    Else
        ' Display a dialog box to select a file to encrypt.
        OpenFileDialog1.InitialDirectory = SrcFolder
        If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            Try
                Dim fName As String = OpenFileDialog1.FileName
                If (Not (fName) Is Nothing) Then
                    Dim fInfo As FileInfo = New FileInfo(fName)
                    ' Use just the file name without path.
                    Dim name As String = fInfo.FullName
                    EncryptFile(name)
                End If
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
        End If
    End If
End Sub

Aggiungere il metodo EncryptFile seguente al form.Add the following EncryptFile method to the form.


private void EncryptFile(string inFile)
{

    // Create instance of Rijndael for
    // symetric encryption of the data.
    RijndaelManaged rjndl = new RijndaelManaged();
    rjndl.KeySize = 256;
    rjndl.BlockSize = 256;
    rjndl.Mode = CipherMode.CBC;
    ICryptoTransform transform = rjndl.CreateEncryptor();

    // Use RSACryptoServiceProvider to
    // enrypt the Rijndael key.
    // rsa is previously instantiated: 
    //    rsa = new RSACryptoServiceProvider(cspp);
    byte[] keyEncrypted = rsa.Encrypt(rjndl.Key, false);

    // Create byte arrays to contain
    // the length values of the key and IV.
    byte[] LenK = new byte[4];
    byte[] LenIV = new byte[4];

    int lKey = keyEncrypted.Length;
    LenK = BitConverter.GetBytes(lKey);
    int lIV = rjndl.IV.Length;
    LenIV = BitConverter.GetBytes(lIV);

    // Write the following to the FileStream
    // for the encrypted file (outFs):
    // - length of the key
    // - length of the IV
    // - ecrypted key
    // - the IV
    // - the encrypted cipher content

    int startFileName = inFile.LastIndexOf("\\") + 1;
   // Change the file's extension to ".enc"
    string outFile = EncrFolder + inFile.Substring(startFileName, inFile.LastIndexOf(".")- startFileName) + ".enc";

    using (FileStream outFs = new FileStream(outFile, FileMode.Create))
    {

            outFs.Write(LenK, 0, 4);
            outFs.Write(LenIV, 0, 4);
            outFs.Write(keyEncrypted, 0, lKey);
            outFs.Write(rjndl.IV, 0, lIV);

            // Now write the cipher text using
            // a CryptoStream for encrypting.
            using (CryptoStream outStreamEncrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write))
            {

                // By encrypting a chunk at
                // a time, you can save memory
                // and accommodate large files.
                int count = 0;
                int offset = 0;

                // blockSizeBytes can be any arbitrary size.
                int blockSizeBytes = rjndl.BlockSize / 8;
                byte[] data = new byte[blockSizeBytes];
                int bytesRead = 0;

                using (FileStream inFs = new FileStream(inFile, FileMode.Open))
                {
                    do
                    {
                        count = inFs.Read(data, 0, blockSizeBytes);
                        offset += count;
                        outStreamEncrypted.Write(data, 0, count);
                        bytesRead += blockSizeBytes;
                    }
                    while (count > 0);
                inFs.Close();
                }
                outStreamEncrypted.FlushFinalBlock();
                outStreamEncrypted.Close();
            }
            outFs.Close();
    }

}
Private Sub EncryptFile(ByVal inFile As String)

    ' Create instance of Rijndael for
    ' symetric encryption of the data.
    Dim rjndl As RijndaelManaged = New RijndaelManaged
    rjndl.KeySize = 256
    rjndl.BlockSize = 256
    rjndl.Mode = CipherMode.CBC
    Dim transform As ICryptoTransform = rjndl.CreateEncryptor

    ' Use RSACryptoServiceProvider to 
    ' enrypt the Rijndael key.
    Dim keyEncrypted() As Byte = rsa.Encrypt(rjndl.Key, False)

    ' Create byte arrays to contain
    ' the length values of the key and IV.
    Dim LenK() As Byte = New Byte((4) - 1) {}
    Dim LenIV() As Byte = New Byte((4) - 1) {}
    Dim lKey As Integer = keyEncrypted.Length
    LenK = BitConverter.GetBytes(lKey)
    Dim lIV As Integer = rjndl.IV.Length
    LenIV = BitConverter.GetBytes(lIV)

    ' Write the following to the FileStream
    ' for the encrypted file (outFs):
    ' - length of the key
    ' - length of the IV
    ' - ecrypted key
    ' - the IV
    ' - the encrypted cipher content
    ' Change the file's extension to ".enc"
    Dim startFileName As Integer = inFile.LastIndexOf("\") + 1
    Dim outFile As String = (EncrFolder _
                + (inFile.Substring(startFileName, inFile.LastIndexOf(".") - startFileName) + ".enc"))

    Using outFs As FileStream = New FileStream(outFile, FileMode.Create)

        outFs.Write(LenK, 0, 4)
        outFs.Write(LenIV, 0, 4)
        outFs.Write(keyEncrypted, 0, lKey)
        outFs.Write(rjndl.IV, 0, lIV)

        ' Now write the cipher text using
        ' a CryptoStream for encrypting.
        Using outStreamEncrypted As CryptoStream = New CryptoStream(outFs, transform, CryptoStreamMode.Write)
            ' By encrypting a chunk at
            ' a time, you can save memory
            ' and accommodate large files.
            Dim count As Integer = 0
            Dim offset As Integer = 0

            ' blockSizeBytes can be any arbitrary size.
            Dim blockSizeBytes As Integer = (rjndl.BlockSize / 8)
            Dim data() As Byte = New Byte((blockSizeBytes) - 1) {}
            Dim bytesRead As Integer = 0
            Using inFs As FileStream = New FileStream(inFile, FileMode.Open)
                Do
                    count = inFs.Read(data, 0, blockSizeBytes)
                    offset = (offset + count)
                    outStreamEncrypted.Write(data, 0, count)
                    bytesRead = (bytesRead + blockSizeBytes)
                Loop Until (count = 0)

                outStreamEncrypted.FlushFinalBlock()
                inFs.Close()
            End Using
            outStreamEncrypted.Close()
        End Using
        outFs.Close()
    End Using
End Sub

Decrittografia di un fileDecrypting a File

Per questa attività vengono usati due metodi: il metodo gestore eventi per il pulsante Decrypt File (buttonEncryptFile_Click) e il metodo DecryptFile.This task involves two methods, the event handler method for the Decrypt File button (buttonEncryptFile_Click), and the DecryptFile method. Il primo metodo visualizza una finestra di dialogo per la selezione di un file e passa il nome file al secondo metodo, che esegue la decrittografia.The first method displays a dialog box for selecting a file and passes its file name to the second method, which performs the decryption.

Il metodo Decrypt esegue le operazioni seguenti:The Decrypt method does the following:

  1. Crea un algoritmo simmetrico RijndaelManaged per decrittografare il contenuto.Creates a RijndaelManaged symmetric algorithm to decrypt the content.

  2. Legge i primi otto byte del pacchetto crittografato FileStream in matrici di byte per ottenere le lunghezze della chiave e del vettore di inizializzazione crittografati.Reads the first eight bytes of the FileStream of the encrypted package into byte arrays to obtain the lengths of the encrypted key and the IV.

  3. Estrae la chiave e il vettore di inizializzazione dal pacchetto di crittografia in matrici di byte.Extracts the key and IV from the encryption package into byte arrays.

  4. Crea un oggetto RSACryptoServiceProvider per decrittografare la chiave RijndaelManaged.Creates an RSACryptoServiceProvider object to decrypt the RijndaelManaged key.

  5. Usa un oggetto CryptoStream per leggere e decrittografare la sezione del testo crittografato del pacchetto di crittografia FileStream, in blocchi di byte, nell'oggetto FileStream per il file decrittografato.Uses a CryptoStream object to read and decrypt the cipher text section of the FileStream encryption package, in blocks of bytes, into the FileStream object for the decrypted file. Quando questa operazione è terminata, la decrittografia è completata.When this is finished, the decryption is completed.

Aggiungere il codice seguente come gestore eventi Click per il pulsante Decrypt File.Add the following code as the Click event handler for the Decrypt File button.

private void buttonDecryptFile_Click(object sender, EventArgs e)
{
    if (rsa == null)
        MessageBox.Show("Key not set.");
    else
    {
        // Display a dialog box to select the encrypted file.
        openFileDialog2.InitialDirectory = EncrFolder;
        if (openFileDialog2.ShowDialog() == DialogResult.OK)
        {
            string fName = openFileDialog2.FileName;
            if (fName != null)
            {
                FileInfo fi = new FileInfo(fName);
                string name = fi.Name;
                DecryptFile(name);
            }
        }
    }
}
Private Sub buttonDecryptFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonDecryptFile.Click
    If rsa Is Nothing Then
        MsgBox("Key not set.")
    Else
        ' Display a dialog box to select the encrypted file.
        OpenFileDialog2.InitialDirectory = EncrFolder
        If (OpenFileDialog2.ShowDialog = Windows.Forms.DialogResult.OK) Then
            Try
                Dim fName As String = OpenFileDialog2.FileName
                If (Not (fName) Is Nothing) Then
                    Dim fi As FileInfo = New FileInfo(fName)
                    Dim name As String = fi.Name
                    DecryptFile(name)
                End If
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        End If
    End If
End Sub

Aggiungere il metodo DecryptFile seguente al form.Add the following DecryptFile method to the form.

private void DecryptFile(string inFile)
{

    // Create instance of Rijndael for
    // symetric decryption of the data.
    RijndaelManaged rjndl = new RijndaelManaged();
    rjndl.KeySize = 256;
    rjndl.BlockSize = 256;
    rjndl.Mode = CipherMode.CBC;

    // Create byte arrays to get the length of
    // the encrypted key and IV.
    // These values were stored as 4 bytes each
    // at the beginning of the encrypted package.
    byte[] LenK = new byte[4];
    byte[] LenIV = new byte[4];

    // Consruct the file name for the decrypted file.
    string outFile = DecrFolder + inFile.Substring(0, inFile.LastIndexOf(".")) + ".txt";

    // Use FileStream objects to read the encrypted
    // file (inFs) and save the decrypted file (outFs).
    using (FileStream inFs = new FileStream(EncrFolder + inFile, FileMode.Open))
    {

        inFs.Seek(0, SeekOrigin.Begin);
        inFs.Seek(0, SeekOrigin.Begin);
        inFs.Read(LenK, 0, 3);
        inFs.Seek(4, SeekOrigin.Begin);
        inFs.Read(LenIV, 0, 3);

        // Convert the lengths to integer values.
        int lenK = BitConverter.ToInt32(LenK, 0);
        int lenIV = BitConverter.ToInt32(LenIV, 0);

        // Determine the start postition of
        // the ciphter text (startC)
        // and its length(lenC).
        int startC = lenK + lenIV + 8;
        int lenC = (int)inFs.Length - startC;

        // Create the byte arrays for
        // the encrypted Rijndael key,
        // the IV, and the cipher text.
        byte[] KeyEncrypted = new byte[lenK];
        byte[] IV = new byte[lenIV];

        // Extract the key and IV
        // starting from index 8
        // after the length values.
        inFs.Seek(8, SeekOrigin.Begin);
        inFs.Read(KeyEncrypted, 0, lenK);
        inFs.Seek(8 + lenK, SeekOrigin.Begin);
        inFs.Read(IV, 0, lenIV);
        Directory.CreateDirectory(DecrFolder);
        // Use RSACryptoServiceProvider
        // to decrypt the Rijndael key.
        byte[] KeyDecrypted = rsa.Decrypt(KeyEncrypted, false);

        // Decrypt the key.
        ICryptoTransform transform = rjndl.CreateDecryptor(KeyDecrypted, IV);

        // Decrypt the cipher text from
        // from the FileSteam of the encrypted
        // file (inFs) into the FileStream
        // for the decrypted file (outFs).
        using (FileStream outFs = new FileStream(outFile, FileMode.Create))
        {

            int count = 0;
            int offset = 0;

            // blockSizeBytes can be any arbitrary size.
            int blockSizeBytes = rjndl.BlockSize / 8;
            byte[] data = new byte[blockSizeBytes];


            // By decrypting a chunk a time,
            // you can save memory and
            // accommodate large files.

            // Start at the beginning
            // of the cipher text.
            inFs.Seek(startC, SeekOrigin.Begin);
            using (CryptoStream outStreamDecrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write))
            {
                do
                {
                    count = inFs.Read(data, 0, blockSizeBytes);
                    offset += count;
                    outStreamDecrypted.Write(data, 0, count);

                }
                while (count > 0);

                outStreamDecrypted.FlushFinalBlock();
                outStreamDecrypted.Close();
            }
            outFs.Close();
        }
        inFs.Close();
    }

}
Private Sub DecryptFile(ByVal inFile As String)
    ' Create instance of Rijndael for
    ' symetric decryption of the data.
    Dim rjndl As RijndaelManaged = New RijndaelManaged
    rjndl.KeySize = 256
    rjndl.BlockSize = 256
    rjndl.Mode = CipherMode.CBC

    ' Create byte arrays to get the length of
    ' the encrypted key and IV.
    ' These values were stored as 4 bytes each
    ' at the beginning of the encrypted package.
    Dim LenK() As Byte = New Byte(4 - 1) {}
    Dim LenIV() As Byte = New Byte(4 - 1) {}

    ' Construct the file name for the decrypted file.
    Dim outFile As String = (DecrFolder _
                + (inFile.Substring(0, inFile.LastIndexOf(".")) + ".txt"))

    ' Use FileStream objects to read the encrypted
    ' file (inFs) and save the decrypted file (outFs).
    Using inFs As FileStream = New FileStream((EncrFolder + inFile), FileMode.Open)

        inFs.Seek(0, SeekOrigin.Begin)
        inFs.Read(LenK, 0, 3)
        inFs.Seek(4, SeekOrigin.Begin)
        inFs.Read(LenIV, 0, 3)

        Dim lengthK As Integer = BitConverter.ToInt32(LenK, 0)
        Dim lengthIV As Integer = BitConverter.ToInt32(LenIV, 0)
        Dim startC As Integer = (lengthK + lengthIV + 8)
        Dim lenC As Integer = (CType(inFs.Length, Integer) - startC)
        Dim KeyEncrypted() As Byte = New Byte(lengthK - 1) {}
        Dim IV() As Byte = New Byte(lengthIV - 1) {}

        ' Extract the key and IV
        ' starting from index 8
        ' after the length values.
        inFs.Seek(8, SeekOrigin.Begin)
        inFs.Read(KeyEncrypted, 0, lengthK)
        inFs.Seek(8 + lengthK, SeekOrigin.Begin)
        inFs.Read(IV, 0, lengthIV)
        Directory.CreateDirectory(DecrFolder)
        ' User RSACryptoServiceProvider
        ' to decryt the Rijndael key
        Dim KeyDecrypted() As Byte = rsa.Decrypt(KeyEncrypted, False)

        ' Decrypt the key.
        Dim transform As ICryptoTransform = rjndl.CreateDecryptor(KeyDecrypted, IV)
        ' Decrypt the cipher text from
        ' from the FileSteam of the encrypted
        ' file (inFs) into the FileStream
        ' for the decrypted file (outFs).
        Using outFs As FileStream = New FileStream(outFile, FileMode.Create)
            Dim count As Integer = 0
            Dim offset As Integer = 0

            ' blockSizeBytes can be any arbitrary size.
            Dim blockSizeBytes As Integer = (rjndl.BlockSize / 8)
            Dim data() As Byte = New Byte(blockSizeBytes - 1) {}
            ' By decrypting a chunk a time,
            ' you can save memory and
            ' accommodate large files.
            ' Start at the beginning
            ' of the cipher text.
            inFs.Seek(startC, SeekOrigin.Begin)
            Using outStreamDecrypted As CryptoStream = New CryptoStream(outFs, transform, CryptoStreamMode.Write)
                Do
                    count = inFs.Read(data, 0, blockSizeBytes)
                    offset = (offset + count)
                    outStreamDecrypted.Write(data, 0, count)
                Loop Until (count = 0)

                outStreamDecrypted.FlushFinalBlock()
                outStreamDecrypted.Close()
            End Using
            outFs.Close()
        End Using
        inFs.Close()
    End Using
End Sub

Esportazione di una chiave pubblicaExporting a Public Key

Questa attività salva la chiave creata dal pulsante Create Keys in un file.This task saves the key created by the Create Keys button to a file. Esporta solo i parametri pubblici.It exports only the public parameters.

Questa attività simula lo scenario in cui Alice fornisce a Bob la sua chiave pubblica affinché egli possa crittografare i file per Alice.This task simulates the scenario of Alice giving Bob her public key so that he can encrypt files for her. Bob e altri utenti che dispongono di quella chiave pubblica non saranno in grado di decrittografarli poiché non possiedono la coppia di chiavi completa con i parametri privati.He and others who have that public key will not be able to decrypt them because they do not have the full key pair with private parameters.

Aggiungere il codice seguente come gestore eventi Click per il pulsante Export Public Key (buttonExportPublicKey_Click).Add the following code as the Click event handler for the Export Public Key button (buttonExportPublicKey_Click).

void buttonExportPublicKey_Click(object sender, System.EventArgs e)
{
    // Save the public key created by the RSA
    // to a file. Caution, persisting the
    // key to a file is a security risk.
    Directory.CreateDirectory(EncrFolder);
    StreamWriter sw = new StreamWriter(PubKeyFile, false);
    sw.Write(rsa.ToXmlString(false));
    sw.Close();
}
Private Sub buttonExportPublicKey_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonExportPublicKey.Click
    ' Save the public key created by the RSA
    ' to a file. Caution, persisting the
    ' key to a file is a security risk.
    Directory.CreateDirectory(EncrFolder)
    Dim sw As StreamWriter = New StreamWriter(PubKeyFile)
    sw.Write(rsa.ToXmlString(False))
    sw.Close()
End Sub

Importazione di una chiave pubblicaImporting a Public Key

Questa attività carica la chiave con solo parametri pubblici, come creati dal pulsante Export Public Key e la imposta come nome del contenitore di chiavi.This task loads the key with only public parameters, as created by the Export Public Key button, and sets it as the key container name.

Questa attività simula lo scenario di Bob che carica la chiave di Alice con solo parametri pubblici in modo che possa crittografare file per conto di Alice.This task simulates the scenario of Bob loading Alice's key with only public parameters so he can encrypt files for her.

Aggiungere il codice seguente come gestore eventi Click per il pulsante Import Public Key (buttonImportPublicKey_Click).Add the following code as the Click event handler for the Import Public Key button (buttonImportPublicKey_Click).

void buttonImportPublicKey_Click(object sender, System.EventArgs e)
{
    StreamReader sr = new StreamReader(PubKeyFile);
    cspp.KeyContainerName = keyName;
    rsa = new RSACryptoServiceProvider(cspp);
    string keytxt = sr.ReadToEnd();
    rsa.FromXmlString(keytxt);
    rsa.PersistKeyInCsp = true;
    if (rsa.PublicOnly == true)
        label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only";
    else
        label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair";
    sr.Close();
}
Private Sub buttonImportPublicKey_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonImportPublicKey.Click
    Dim sr As StreamReader = New StreamReader(PubKeyFile)
    cspp.KeyContainerName = keyName
    rsa = New RSACryptoServiceProvider(cspp)
    Dim keytxt As String = sr.ReadToEnd
    rsa.FromXmlString(keytxt)
    rsa.PersistKeyInCsp = True
    If rsa.PublicOnly = True Then
        Label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only"
    Else
        Label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair"
    End If
    sr.Close()
End Sub

Recupero di una chiave privataGetting a Private Key

Questa attività imposta il nome del contenitore di chiavi sul nome della chiave creata mediante il pulsante Create Keys.This task sets the key container name to the name of the key created by using the Create Keys button. Il contenitore di chiavi conterrà la coppia di chiavi completa con parametri privati.The key container will contain the full key pair with private parameters.

Questa attività simula lo scenario di Alice che usa la propria chiave privata per decrittografare file crittografati da Bob.This task simulates the scenario of Alice using her private key to decrypt files encrypted by Bob.

Aggiungere il codice seguente come gestore eventi Click per il pulsante Get Private Key (buttonGetPrivateKey_Click).Add the following code as the Click event handler for the Get Private Key button (buttonGetPrivateKey_Click).

private void buttonGetPrivateKey_Click(object sender, EventArgs e)
{
    cspp.KeyContainerName = keyName;

    rsa = new RSACryptoServiceProvider(cspp);
    rsa.PersistKeyInCsp = true;

    if (rsa.PublicOnly == true)
        label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only";
    else
        label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair";

}
Private Sub buttonGetPrivateKey_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles buttonGetPrivateKey.Click
    cspp.KeyContainerName = keyName
    rsa = New RSACryptoServiceProvider(cspp)
    rsa.PersistKeyInCsp = True
    If rsa.PublicOnly = True Then
        Label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only"
    Else
        Label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair"
    End If
End Sub

Verifica dell'applicazioneTesting the Application

Dopo aver compilato l'applicazione, eseguire gli scenari di test seguenti.After you have built the application, perform the following testing scenarios.

Per creare chiavi, crittografare e decrittografareTo create keys, encrypt, and decrypt

  1. Fare clic sul pulsante Create Keys.Click the Create Keys button. L'etichetta visualizza il nome della chiave e mostra che è una coppia di chiavi completa.The label displays the key name and shows that it is a full key pair.

  2. Fare clic sul pulsante Export Public Key.Click the Export Public Key button. Si noti che l'esportazione dei parametri della chiave pubblica non modifica la chiave corrente.Note that exporting the public key parameters does not change the current key.

  3. Fare clic sul pulsante Encrypt File e selezionare un file.Click the Encrypt File button and select a file.

  4. Fare clic sul pulsante Decrypt File e selezionare il file appena crittografato.Click the Decrypt File button and select the file just encrypted.

  5. Esaminare il file appena decrittografato.Examine the file just decrypted.

  6. Chiudere l'applicazione e riavviarla per testare il recupero dei contenitori di chiavi persistenti nello scenario successivo.Close the application and restart it to test retrieving persisted key containers in the next scenario.

Per crittografare mediante la chiave pubblicaTo encrypt using the public key

  1. Fare clic sul pulsante Import Public Key.Click the Import Public Key button. L'etichetta visualizza il nome della chiave e mostra che è solo pubblica.The label displays the key name and shows that it is public only.

  2. Fare clic sul pulsante Encrypt File e selezionare un file.Click the Encrypt File button and select a file.

  3. Fare clic sul pulsante Decrypt File e selezionare il file appena crittografato.Click the Decrypt File button and select the file just encrypted. Questa operazione avrà esito negativo perché si deve avere a disposizione la chiave privata per decrittografare.This will fail because you must have the private key to decrypt.

Questo scenario illustra una situazione in cui si possiede solo la chiave pubblica per crittografare un file per un'altra persona.This scenario demonstrates having only the public key to encrypt a file for another person. In genere quella persona potrebbe mettere a disposizione solo la chiave pubblica e mantenere quella privata per la decrittografia.Typically that person would give you only the public key and withhold the private key for decryption.

Per decrittografare mediante la chiave privataTo decrypt using the private key

  1. Fare clic sul pulsante Get Private Key.Click the Get Private Key button. L'etichetta visualizza il nome della chiave e mostra se è la coppia di chiavi completa.The label displays the key name and shows whether it is the full key pair.

  2. Fare clic sul pulsante Decrypt File e selezionare il file appena crittografato.Click the Decrypt File button and select the file just encrypted. Questa operazione avrà esito positivo perché si possiede la coppia di chiavi completa per decrittografare.This will be successful because you have the full key pair to decrypt.

Vedere ancheSee Also

Cryptographic ServicesCryptographic Services