Procedura dettagliata: creazione di un'applicazione di crittografia

Aggiornamento: novembre 2007

In questa procedura dettagliata viene illustrato come crittografare e decrittografare il contenuto. Gli esempi di codice sono stati creati per un'applicazione Windows Form. Nell'applicazione non vengono descritti scenari reali, ad esempio l'utilizzo di smart card, ma vengono illustrate le nozioni fondamentali sulla crittografia e la decrittografia.

In questa procedura dettagliata vengono utilizzate le linee guida seguenti per la crittografia:

  • Viene utilizzata la classe RijndaelManaged, un algoritmo simmetrico, per crittografare e decrittografare i dati utilizzando le proprietà Key e IV generate automaticamente.

  • Viene utilizzata la classe RSACryptoServiceProvider, un algoritmo asimmetrico, per crittografare e decrittografare la chiave nei dati crittografati dalla classe RijndaelManaged. Gli algoritmi asimmetrici sono particolarmente adatti per quantità ridotte di dati, ad esempio una chiave.

    Nota:

    Se lo scopo è proteggere i dati del computer anziché scambiare contenuto crittografato con altri utenti, utilizzare la classe ProtectedData o ProtectedMemory.

Nella tabella riportata di seguito vengono riassunte le attività di crittografia di questo argomento.

Attività

Descrizione

Creazione di un'applicazione Windows Form

Vengono elencati i controlli necessari per eseguire l'applicazione.

Dichiarazione di oggetti globali

Vengono dichiarate le variabili di percorso di stringa, l'oggetto CspParameters e l'oggetto RSACryptoServiceProvider per ottenere il contesto globale della classe Form.

Creazione di una chiave asimmetrica

Viene creata una coppia di valori di chiavi pubblica/privata a cui viene assegnato un nome di contenitore di chiavi.

Crittografia di un file

Viene visualizzata una finestra di dialogo in cui selezionare un file da crittografare e viene crittografato il file.

Decrittografia di un file

Viene visualizzata una finestra di dialogo in cui selezionare un file crittografato da decrittografare e viene decrittografato il file.

Ottenimento di una chiave privata

Si ottiene la coppia di chiavi completa con il nome del contenitore di chiavi.

Esportazione di una chiave pubblica

Viene salvata la chiave in un file XML solo con parametri pubblici.

Importazione di una chiave pubblica

Viene caricata la chiave da un file XML nel contenitore di chiavi.

Test dell'applicazione

Vengono elencate le procedure per testare l'applicazione.

Prerequisiti

Per completare questa procedura dettagliata, è necessario disporre dei seguenti componenti:

Creazione di un'applicazione Windows Form

La maggior parte degli esempi di codice riportati in questa procedura dettagliata è stata creata come gestore eventi di controlli pulsante. Nella tabella riportata di seguito vengono elencati i controlli richiesti per l'applicazione di esempio e i relativi nomi obbligatori corrispondenti agli esempi di codice.

Controllo

Nome

Proprietà Text (se richiesta)

Button

buttonEncryptFile

Encrypt File

Button

buttonDecryptFile

Decrypt File

Button

buttonCreateAsmKeys

Create Keys

Button

buttonExportPublicKey

Export Public Key

Button

buttonImportPublicKey

Import Public Key

Button

buttonGetPrivateKey

Get Private Key

Label

label1

OpenFileDialog

openFileDialog1

OpenFileDialog

openFileDialog2

Fare doppio clic sui pulsanti nella finestra di progettazione di Visual Studio per creare i gestori eventi associati.

Dichiarazione di oggetti globali

Aggiungere il codice riportato di seguito al costruttore del form. Modificare le variabili di tipo stringa per l'ambiente e le preferenze.

' 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"
// 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";

Creazione di una chiave asimmetrica

L'attività crea una chiave asimmetrica che esegue la crittografia e decrittografia della chiave RijndaelManaged. La chiave è stata utilizzata per crittografare il contenuto. Il nome del contenitore di chiavi viene visualizzato sul controllo etichetta.

Aggiungere il codice riportato di seguito come gestore eventi Click del pulsante Create Keys (buttonCreateAsmKeys_Click).

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
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";

}

Crittografia di un file

Per questa attività vengono utilizzati due metodi: il metodo per la gestione eventi del pulsante Encrypt File (buttonEncryptFile_Click) e il metodo EncryptFile. Il primo metodo consente di visualizzare una finestra di dialogo per la selezione di un file e passa il nome del file al secondo metodo, che esegue la crittografia.

Il contenuto crittografato, la chiave e il vettore di inizializzazione vengono salvati in un unico oggetto FileStream a cui viene fatto riferimento come package di crittografia.

Il metodo EncryptFile consente di effettuare le seguenti operazioni:

  1. Creare un algoritmo simmetrico RijndaelManaged per crittografare il contenuto.

  2. Creare un oggetto RSACryptoServiceProvider per eseguire la crittografia della chiave RijndaelManaged.

  3. Utilizzare un oggetto CryptoStream per eseguire la lettura e la crittografia dell'oggetto FileStream del file di origine, in blocchi di byte, in un oggetto FileStream di destinazione del file crittografato.

  4. Determinare le lunghezze della chiave crittografata e del vettore di inizializzazione e creare matrici di byte dei valori delle lunghezze.

  5. Scrivere la chiave, il vettore di inizializzazione e le relative lunghezze nel package crittografato.

Il package di crittografia utilizza il formato seguente:

  • Lunghezza della chiave, byte 0 - 3

  • Lunghezza del vettore di inizializzazione, byte 4 - 7

  • Chiave crittografata

  • Vettore di inizializzazione

  • Testo crittografato

Le lunghezze della chiave e del vettore di inizializzazione consentono di determinare i punti iniziali e la lunghezza di tutte le parti del package di crittografia utilizzabili per decrittografare il file.

Aggiungere il codice riportato di seguito come gestore eventi Click del pulsante Encrypt File (buttonEncryptFile_Click).

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.Name
                    EncryptFile(name)
                End If
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
        End If
    End If
End Sub
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.Name;
                EncryptFile(name);
            }
        }
    }
}

Aggiungere il metodo EncryptFile seguente al form.

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 outFile As String = (EncrFolder _
                + (inFile.Substring(0, inFile.LastIndexOf(".")) + ".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
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.
    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

   // Change the file's extension to ".enc"
    string outFile = EncrFolder + inFile.Substring(0, inFile.LastIndexOf(".")) + ".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();
    }

}

Decrittografia di un file

Per questa attività vengono utilizzati due metodi: il metodo per la gestione eventi del pulsante Decrypt File (buttonEncryptFile_Click) e il metodo DecryptFile. Il primo metodo visualizza una finestra di dialogo per la selezione di un file e passa il nome del file al secondo metodo, che esegue la decrittografia.

Il metodo Decrypt consente di effettuare le seguenti operazioni:

  1. Creare un algoritmo simmetrico RijndaelManaged per decrittografare il contenuto.

  2. Leggere i primi otto byte della classe FileStream del package crittografato in matrici di byte per ottenere le lunghezze della chiave crittografata e del vettore di inizializzazione.

  3. Estrarre la chiave e il vettore di inizializzazione dal package di crittografia in matrici di byte.

  4. Creare un oggetto RSACryptoServiceProvider per eseguire la decrittografia della chiave RijndaelManaged.

  5. Utilizzare un oggetto CryptoStream per eseguire la lettura e la decrittografia della sezione di testo crittografato del package di crittografia FileStream, in blocchi di byte, nell'oggetto FileStream del file decrittografato. Al termine di questa operazione, la decrittografia è completa.

Aggiungere il codice riportato di seguito come gestore eventi Click del pulsante Decrypt File.

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
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);
            }
        }
    }
}

Aggiungere il metodo DecryptFile seguente al form.

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)
        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
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;
    rjndl.Padding = PaddingMode.None;

    // 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);

        // 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();
    }

}

Esportazione di una chiave pubblica

Con questa attività la chiave creata dal pulsante Create Keys viene salvata in un file e vengono esportati unicamente i parametri pubblici.

Con questa attività si simula lo scenario di un utente che fornisce a un altro utente la propria chiave pubblica in modo che possa crittografare i file per suo conto. L'utente e altri eventuali utenti che dispongono della chiave pubblica non saranno comunque in grado di decrittografare i file perché non dispongono della coppia di chiavi completa con i parametri privati.

Aggiungere il codice riportato di seguito come gestore eventi Click del pulsante Export Public Key (buttonExportPublicKey_Click).

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.
    Dim sw As StreamWriter = New StreamWriter(PubKeyFile)
    sw.Write(rsa.ToXmlString(False))
    sw.Close()
End Sub
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.
    StreamWriter sw = new StreamWriter(PubKeyFile);
    sw.Write(rsa.ToXmlString(false));
    sw.Close();
}

Importazione di una chiave pubblica

Con questa attività nella chiave vengono caricati soltanto i parametri pubblici, così come sono stati creati con il pulsante Export Public Key. La chiave viene impostata come nome del contenitore di chiavi.

Con questa attività si simula lo scenario di un utente che carica la chiave di un altro utente solo con parametri pubblici in modo da poter crittografare i file per suo conto.

Aggiungere il codice riportato di seguito come gestore eventi Click del pulsante Import Public Key (buttonImportPublicKey_Click).

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
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();
}

Ottenimento di una chiave privata

Con questa attività viene impostato il nome del contenitore di chiavi in base al nome della chiave creata tramite il pulsante Create Keys. Il contenitore di chiavi conterrà la coppia di chiavi completa con parametri privati.

Con questa attività si simula lo scenario di un utente che utilizza la propria chiave privata per decrittografare i file crittografati da un altro utente.

Aggiungere il codice riportato di seguito come gestore eventi Click del pulsante Get Private Key (buttonGetPrivateKey_Click).

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
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";

}

Test dell'applicazione

Dopo aver compilato l'applicazione, eseguire gli scenari di test seguenti.

Per creare chiavi, crittografare e decrittografare

  1. Fare clic sul pulsante Create Keys. Nell'etichetta verrà indicato il nome della chiave e che si tratta di una coppia di chiavi completa.

  2. Fare clic sul pulsante Export Public Key. Esportando i parametri della chiave pubblica, la chiave corrente non cambia.

  3. Fare clic sul pulsante Encrypt File e selezionare un file.

  4. Fare clic sul pulsante Decrypt File e selezionare il file appena crittografato.

  5. Esaminare il file appena decrittografato.

  6. Chiudere l'applicazione e riavviarla per verificare il recupero dei contenitori di chiavi persistenti nello scenario successivo.

Per eseguire la crittografia utilizzando la chiave pubblica

  1. Fare clic sul pulsante Import Public Key. Nell'etichetta verrà indicato il nome della chiave e che si tratta di una chiave solo pubblica.

  2. Fare clic sul pulsante Encrypt File e selezionare un file.

  3. Fare clic sul pulsante Decrypt File e selezionare il file appena crittografato. L'operazione non riuscirà perché è necessario disporre della chiave privata per eseguire la decrittografia.

In questo scenario viene descritta una situazione in cui si dispone solo della chiave pubblica per crittografare un file per un altro utente. In genere l'utente fornirà solo la chiave pubblica e manterrà la chiave privata per la decrittografia.

Per eseguire la decrittografia utilizzando la chiave privata

  1. Fare clic sul pulsante Get Private Key. Nell'etichetta verrà indicato il nome della chiave e se si tratta di una coppia di chiavi completa.

  2. Fare clic sul pulsante Decrypt File e selezionare il file appena crittografato. L'operazione riuscirà perché si dispone della coppia di chiavi completa per la decrittografia.

Vedere anche

Altre risorse

Attività di crittografia

Servizi di crittografia