Przewodnik: tworzenie aplikacji kryptograficznych

Uwaga

Ten artykuł dotyczy systemu Windows.

Aby uzyskać informacje o ASP.NET Core, zobacz ASP.NET Core Data Protection.

W tym przewodniku pokazano, jak szyfrować i odszyfrowywać zawartość pliku. Przykłady kodu są przeznaczone dla aplikacji Windows Forms. Ta aplikacja nie demonstruje rzeczywistych scenariuszy, takich jak używanie kart inteligentnych. Zamiast tego demonstruje podstawy szyfrowania i odszyfrowywania.

W tym przewodniku użyto następujących wskazówek dotyczących szyfrowania:

  • Aes Użyj klasy, algorytmu symetrycznego, aby szyfrować i odszyfrowywać dane przy użyciu automatycznie generowanych Key i IV.

  • Użyj algorytmu RSA asymetrycznego, aby zaszyfrować i odszyfrować klucz do danych zaszyfrowanych przez usługę Aes. Algorytmy asymetryczne najlepiej nadają się do mniejszych ilości danych, takich jak klucz.

    Uwaga

    Jeśli chcesz chronić dane na komputerze zamiast wymieniać zaszyfrowaną zawartość z innymi osobami, rozważ użycie ProtectedData klasy .

Poniższa tabela zawiera podsumowanie zadań kryptograficznych w tym temacie.

Zadanie Opis
Tworzenie aplikacji Windows Forms Wyświetla listę kontrolek wymaganych do uruchomienia aplikacji.
Deklarowanie obiektów globalnych Deklaruje zmienne ścieżki ciągu , CspParametersi , RSACryptoServiceProvider aby mieć kontekst Form globalny klasy.
Tworzenie klucza asymetrycznego Tworzy asymetryczną parę klucz-wartość klucza publicznego i prywatnego i przypisuje mu nazwę kontenera klucza.
Szyfrowanie pliku Wyświetla okno dialogowe, aby wybrać plik do szyfrowania i zaszyfrować plik.
Odszyfrowywanie pliku Wyświetla okno dialogowe służące do wybierania zaszyfrowanego pliku na potrzeby odszyfrowywania i odszyfrowywania pliku.
Uzyskiwanie klucza prywatnego Pobiera pełną parę kluczy przy użyciu nazwy kontenera kluczy.
Eksportowanie klucza publicznego Zapisuje klucz w pliku XML tylko z parametrami publicznymi.
Importowanie klucza publicznego Ładuje klucz z pliku XML do kontenera kluczy.
Testowanie aplikacji Wyświetla listę procedur testowania tej aplikacji.

Wymagania wstępne

Następujące składniki są wymagane do przeprowadzenia tego instruktażu:

Tworzenie aplikacji Windows Forms

Większość przykładów kodu w tym przewodniku jest przeznaczona do obsługi zdarzeń dla kontrolek przycisków. W poniższej tabeli wymieniono kontrolki wymagane dla przykładowej aplikacji i ich wymagane nazwy zgodne z przykładami kodu.

Kontrola Nazwa Właściwość Text (zgodnie z potrzebami)
Button buttonEncryptFile Szyfrowanie pliku
Button buttonDecryptFile Odszyfrowywanie pliku
Button buttonCreateAsmKeys Tworzenie kluczy
Button buttonExportPublicKey Eksportowanie klucza publicznego
Button buttonImportPublicKey Importowanie klucza publicznego
Button buttonGetPrivateKey Uzyskiwanie klucza prywatnego
Label label1 Klucz nie jest ustawiony
OpenFileDialog _encryptOpenFileDialog
OpenFileDialog _decryptOpenFileDialog

Kliknij dwukrotnie przyciski w projektancie programu Visual Studio, aby utworzyć programy obsługi zdarzeń.

Deklarowanie obiektów globalnych

Dodaj następujący kod w ramach deklaracji klasy Form1. Edytuj zmienne ciągu dla środowiska i preferencji.

// Declare CspParameters and RsaCryptoServiceProvider
// objects with global scope of your Form class.
readonly 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 CspParameters and RsaCryptoServiceProvider
' objects with global scope of your Form class.
ReadOnly _cspp As New CspParameters
Dim _rsa As RSACryptoServiceProvider

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

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

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

Tworzenie klucza asymetrycznego

To zadanie tworzy klucz asymetryczny, który szyfruje i odszyfrowuje Aes klucz. Ten klucz był używany do szyfrowania zawartości i wyświetla nazwę kontenera kluczy w kontrolce etykiety.

Dodaj następujący kod jako procedurę ClickCreate Keys obsługi zdarzeń dla przycisku (buttonCreateAsmKeys_Click).

private void buttonCreateAsmKeys_Click(object sender, EventArgs e)
{
    // Stores a key pair in the key container.
    _cspp.KeyContainerName = KeyName;
    _rsa = new RSACryptoServiceProvider(_cspp)
    {
        PersistKeyInCsp = true
    };

    label1.Text = _rsa.PublicOnly
        ? $"Key: {_cspp.KeyContainerName} - Public Only"
        : $"Key: {_cspp.KeyContainerName} - Full Key Pair";
}
Private Sub buttonCreateAsmKeys_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonCreateAsmKeys.Click
    ' Stores a key pair in the key container.
    _cspp.KeyContainerName = KeyName
    _rsa = New RSACryptoServiceProvider(_cspp) With {
        .PersistKeyInCsp = True
    }

    If _rsa.PublicOnly Then
        Label1.Text = $"Key: {_cspp.KeyContainerName} - Public Only"
    Else
        Label1.Text = $"Key: {_cspp.KeyContainerName} - Full Key Pair"
    End If

End Sub

Szyfrowanie pliku

To zadanie obejmuje dwie metody: metodę obsługi zdarzeń dla Encrypt File przycisku (buttonEncryptFile_Click) i metodę EncryptFile . Pierwsza metoda wyświetla okno dialogowe wyboru pliku i przekazuje nazwę pliku do drugiej metody, która wykonuje szyfrowanie.

Zaszyfrowana zawartość, klucz i IV są zapisywane w jednym FileStream, który jest nazywany pakietem szyfrowania.

Metoda EncryptFile wykonuje następujące czynności:

  1. Aes Tworzy algorytm symetryczny do szyfrowania zawartości.
  2. RSACryptoServiceProvider Tworzy obiekt do szyfrowania Aes klucza.
  3. CryptoStream Używa obiektu do odczytywania i szyfrowania FileStream pliku źródłowego w blokach bajtów do obiektu docelowego FileStream dla zaszyfrowanego pliku.
  4. Określa długość zaszyfrowanego klucza i IV oraz tworzy tablice bajtów ich wartości długości.
  5. Zapisuje wartości Klucza, IV i ich długości w zaszyfrowanym pakiecie.

Pakiet szyfrowania używa następującego formatu:

  • Długość klucza, bajty 0–3
  • Długość IV, bajty 4 –7
  • Zaszyfrowany klucz
  • IV
  • Tekst szyfrowania

Możesz użyć długości klucza i IV, aby określić punkty początkowe i długości wszystkich części pakietu szyfrowania, które następnie można użyć do odszyfrowywania pliku.

Dodaj następujący kod jako procedurę ClickEncrypt File obsługi zdarzeń dla przycisku (buttonEncryptFile_Click).

private void buttonEncryptFile_Click(object sender, EventArgs e)
{
    if (_rsa is null)
    {
        MessageBox.Show("Key not set.");
    }
    else
    {
        // Display a dialog box to select a file to encrypt.
        _encryptOpenFileDialog.InitialDirectory = SrcFolder;
        if (_encryptOpenFileDialog.ShowDialog() == DialogResult.OK)
        {
            string fName = _encryptOpenFileDialog.FileName;
            if (fName != null)
            {
                // Pass the file name without the path.
                EncryptFile(new FileInfo(fName));
            }
        }
    }
}
Private Sub buttonEncryptFile_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonEncryptFile.Click
    If _rsa Is Nothing Then
        MsgBox("Key not set.")
    Else
        ' Display a dialog box to select a file to encrypt.
        _encryptOpenFileDialog.InitialDirectory = SrcFolder
        If _encryptOpenFileDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
            Try
                Dim fName As String = _encryptOpenFileDialog.FileName
                If (Not (fName) Is Nothing) Then
                    Dim fInfo As 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

Dodaj następującą EncryptFile metodę do formularza.

private void EncryptFile(FileInfo file)
{
    // Create instance of Aes for
    // symmetric encryption of the data.
    Aes aes = Aes.Create();
    ICryptoTransform transform = aes.CreateEncryptor();

    // Use RSACryptoServiceProvider to
    // encrypt the AES key.
    // rsa is previously instantiated:
    //    rsa = new RSACryptoServiceProvider(cspp);
    byte[] keyEncrypted = _rsa.Encrypt(aes.Key, false);

    // Create byte arrays to contain
    // the length values of the key and IV.
    int lKey = keyEncrypted.Length;
    byte[] LenK = BitConverter.GetBytes(lKey);
    int lIV = aes.IV.Length;
    byte[] LenIV = BitConverter.GetBytes(lIV);

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

    // Change the file's extension to ".enc"
    string outFile =
        Path.Combine(EncrFolder, Path.ChangeExtension(file.Name, ".enc"));

    using (var outFs = new FileStream(outFile, FileMode.Create))
    {
        outFs.Write(LenK, 0, 4);
        outFs.Write(LenIV, 0, 4);
        outFs.Write(keyEncrypted, 0, lKey);
        outFs.Write(aes.IV, 0, lIV);

        // Now write the cipher text using
        // a CryptoStream for encrypting.
        using (var 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 = aes.BlockSize / 8;
            byte[] data = new byte[blockSizeBytes];
            int bytesRead = 0;

            using (var inFs = new FileStream(file.FullName, FileMode.Open))
            {
                do
                {
                    count = inFs.Read(data, 0, blockSizeBytes);
                    offset += count;
                    outStreamEncrypted.Write(data, 0, count);
                    bytesRead += blockSizeBytes;
                } while (count > 0);
            }
            outStreamEncrypted.FlushFinalBlock();
        }
    }
}
Private Sub EncryptFile(ByVal inFile As String)
    ' Create instance of Aes for
    ' symmetric encryption of the data.
    Dim aes As Aes = Aes.Create()
    Dim transform As ICryptoTransform = aes.CreateEncryptor

    ' Use RSACryptoServiceProvider to
    ' encrypt the AES key.
    Dim keyEncrypted() As Byte = _rsa.Encrypt(aes.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 = aes.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
    ' - encrypted 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 New FileStream(outFile, FileMode.Create)
        outFs.Write(LenK, 0, 4)
        outFs.Write(LenIV, 0, 4)
        outFs.Write(keyEncrypted, 0, lKey)
        outFs.Write(aes.IV, 0, lIV)

        ' Now write the cipher text using
        ' a CryptoStream for encrypting.
        Using outStreamEncrypted As 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 = (aes.BlockSize / 8)
            Dim data() As Byte = New Byte((blockSizeBytes) - 1) {}
            Dim bytesRead As Integer = 0
            Using inFs As 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

Odszyfrowywanie pliku

To zadanie obejmuje dwie metody, metodę Decrypt File obsługi zdarzeń dla przycisku (buttonDecryptFile_Click) i metodę DecryptFile . Pierwsza metoda wyświetla okno dialogowe wyboru pliku i przekazuje nazwę pliku do drugiej metody, która wykonuje odszyfrowywanie.

Metoda Decrypt wykonuje następujące czynności:

  1. Aes Tworzy algorytm symetryczny do odszyfrowywania zawartości.
  2. Odczytuje pierwsze osiem bajtów FileStream zaszyfrowanego pakietu do tablic bajtowych w celu uzyskania długości zaszyfrowanego klucza i iv.
  3. Wyodrębnia klucz i IV z pakietu szyfrowania do tablic bajtowych.
  4. RSACryptoServiceProvider Tworzy obiekt do odszyfrowywania Aes klucza.
  5. CryptoStream Używa obiektu do odczytywania i odszyfrowywania sekcji FileStream tekstu szyfrowania pakietu szyfrowania w blokach bajtów do FileStream obiektu dla odszyfrowanego pliku. Po zakończeniu odszyfrowywanie zostanie ukończone.

Dodaj następujący kod jako procedurę ClickDecrypt File obsługi zdarzeń dla przycisku.

private void buttonDecryptFile_Click(object sender, EventArgs e)
{
    if (_rsa is null)
    {
        MessageBox.Show("Key not set.");
    }
    else
    {
        // Display a dialog box to select the encrypted file.
        _decryptOpenFileDialog.InitialDirectory = EncrFolder;
        if (_decryptOpenFileDialog.ShowDialog() == DialogResult.OK)
        {
            string fName = _decryptOpenFileDialog.FileName;
            if (fName != null)
            {
                DecryptFile(new FileInfo(fName));
            }
        }
    }
}
Private Sub buttonDecryptFile_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonDecryptFile.Click
    If _rsa Is Nothing Then
        MsgBox("Key not set.")
    Else
        ' Display a dialog box to select the encrypted file.
        _decryptOpenFileDialog.InitialDirectory = EncrFolder
        If (_decryptOpenFileDialog.ShowDialog = Windows.Forms.DialogResult.OK) Then
            Try
                Dim fName As String = _decryptOpenFileDialog.FileName
                If ((fName) IsNot Nothing) Then
                    Dim fi As 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

Dodaj następującą DecryptFile metodę do formularza.

private void DecryptFile(FileInfo file)
{
    // Create instance of Aes for
    // symmetric decryption of the data.
    Aes aes = Aes.Create();

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

    // Construct the file name for the decrypted file.
    string outFile =
        Path.ChangeExtension(file.FullName.Replace("Encrypt", "Decrypt"), ".txt");

    // Use FileStream objects to read the encrypted
    // file (inFs) and save the decrypted file (outFs).
    using (var inFs = new FileStream(file.FullName, FileMode.Open))
    {
        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 position of
        // the cipher text (startC)
        // and its length(lenC).
        int startC = lenK + lenIV + 8;
        int lenC = (int)inFs.Length - startC;

        // Create the byte arrays for
        // the encrypted Aes 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 AES key.
        byte[] KeyDecrypted = _rsa.Decrypt(KeyEncrypted, false);

        // Decrypt the key.
        ICryptoTransform transform = aes.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 (var outFs = new FileStream(outFile, FileMode.Create))
        {
            int count = 0;
            int offset = 0;

            // blockSizeBytes can be any arbitrary size.
            int blockSizeBytes = aes.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 (var 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();
            }
        }
    }
}
Private Sub DecryptFile(ByVal inFile As String)
    ' Create instance of Aes for
    ' symmetric decryption of the data.
    Dim aes As Aes = Aes.Create()

    ' 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 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 decrypt the AES key
        Dim KeyDecrypted() As Byte = _rsa.Decrypt(KeyEncrypted, False)

        ' Decrypt the key.
        Dim transform As ICryptoTransform = aes.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 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 = (aes.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 New CryptoStream(outFs, transform, CryptoStreamMode.Write)
                Do
                    count = inFs.Read(data, 0, blockSizeBytes)
                    offset += count
                    outStreamDecrypted.Write(data, 0, count)
                Loop Until (count = 0)

                outStreamDecrypted.FlushFinalBlock()
            End Using
        End Using
    End Using
End Sub

Eksportowanie klucza publicznego

To zadanie zapisuje klucz utworzony przez Create Keys przycisk do pliku. Eksportuje tylko parametry publiczne.

To zadanie symuluje scenariusz Alicji dając jej klucz publiczny, aby mógł zaszyfrować pliki dla niej. On i inni, którzy mają ten klucz publiczny, nie będą mogli ich odszyfrować, ponieważ nie mają pełnej pary kluczy z parametrami prywatnymi.

Dodaj następujący kod jako procedurę ClickExport Public Key obsługi zdarzeń dla przycisku (buttonExportPublicKey_Click).

void buttonExportPublicKey_Click(object sender, 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);
    using (var sw = new StreamWriter(PubKeyFile, false))
    {
        sw.Write(_rsa.ToXmlString(false));
    }
}
Private Sub buttonExportPublicKey_Click(ByVal sender As Object, ByVal e As 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)
    Using sw As New StreamWriter(PubKeyFile)
        sw.Write(_rsa.ToXmlString(False))
    End Using
End Sub

Importowanie klucza publicznego

To zadanie ładuje klucz tylko z parametrami publicznymi, utworzonymi przez Export Public Key przycisk, i ustawia go jako nazwę kontenera kluczy.

To zadanie symuluje scenariusz ładowania klucza Alicji tylko z parametrami publicznymi, aby mógł zaszyfrować pliki dla niej.

Dodaj następujący kod jako procedurę Click obsługi zdarzeń dla Import Public Key przycisku (buttonImportPublicKey_Click).

void buttonImportPublicKey_Click(object sender, EventArgs e)
{
    using (var sr = new StreamReader(PubKeyFile))
    {
        _cspp.KeyContainerName = KeyName;
        _rsa = new RSACryptoServiceProvider(_cspp);

        string keytxt = sr.ReadToEnd();
        _rsa.FromXmlString(keytxt);
        _rsa.PersistKeyInCsp = true;

        label1.Text = _rsa.PublicOnly
            ? $"Key: {_cspp.KeyContainerName} - Public Only"
            : $"Key: {_cspp.KeyContainerName} - Full Key Pair";
    }
}
Private Sub buttonImportPublicKey_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonImportPublicKey.Click
    Using sr As 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 Then
            Label1.Text = $"Key: {_cspp.KeyContainerName} - Public Only"
        Else
            Label1.Text = $"Key: {_cspp.KeyContainerName} - Full Key Pair"
        End If
    End Using
End Sub

Uzyskiwanie klucza prywatnego

To zadanie ustawia nazwę kontenera kluczy na nazwę klucza utworzonego Create Keys przy użyciu przycisku . Kontener kluczy będzie zawierać pełną parę kluczy z parametrami prywatnymi.

To zadanie symuluje scenariusz Alice przy użyciu jej klucza prywatnego do odszyfrowywania plików zaszyfrowanych przez Boba.

Dodaj następujący kod jako procedurę Click obsługi zdarzeń dla Get Private Key przycisku (buttonGetPrivateKey_Click).

private void buttonGetPrivateKey_Click(object sender, EventArgs e)
{
    _cspp.KeyContainerName = KeyName;
    _rsa = new RSACryptoServiceProvider(_cspp)
    {
        PersistKeyInCsp = true
    };

    label1.Text = _rsa.PublicOnly
        ? $"Key: {_cspp.KeyContainerName} - Public Only"
        : $"Key: {_cspp.KeyContainerName} - Full Key Pair";
}
Private Sub buttonGetPrivateKey_Click(ByVal sender As Object,
    ByVal e As EventArgs) Handles buttonGetPrivateKey.Click
    _cspp.KeyContainerName = KeyName
    _rsa = New RSACryptoServiceProvider(_cspp) With {
        .PersistKeyInCsp = True
    }
    If _rsa.PublicOnly Then
        Label1.Text = $"Key: {_cspp.KeyContainerName} - Public Only"
    Else
        Label1.Text = $"Key: {_cspp.KeyContainerName} - Full Key Pair"
    End If
End Sub

Testowanie aplikacji

Po skompiluj aplikację, wykonaj następujące scenariusze testowania.

Aby utworzyć klucze, zaszyfrować i odszyfrować

  1. Kliknij przycisk Create Keys. Etykieta wyświetla nazwę klucza i pokazuje, że jest to pełna para kluczy.
  2. Kliknij przycisk Export Public Key. Należy pamiętać, że eksportowanie parametrów klucza publicznego nie zmienia bieżącego klucza.
  3. Encrypt File Kliknij przycisk i wybierz plik.
  4. Decrypt File Kliknij przycisk i wybierz plik po prostu zaszyfrowany.
  5. Sprawdź plik właśnie odszyfrowany.
  6. Zamknij aplikację i uruchom ją ponownie, aby przetestować pobieranie utrwalonego kontenera kluczy w następnym scenariuszu.

Aby zaszyfrować przy użyciu klucza publicznego

  1. Kliknij przycisk Import Public Key. Etykieta wyświetla nazwę klucza i pokazuje, że jest ona publiczna.
  2. Encrypt File Kliknij przycisk i wybierz plik.
  3. Decrypt File Kliknij przycisk i wybierz plik po prostu zaszyfrowany. Nie powiedzie się to, ponieważ konieczne jest odszyfrowanie klucza prywatnego.

W tym scenariuszu pokazano, że klucz publiczny służy tylko do szyfrowania pliku dla innej osoby. Zazwyczaj ta osoba da ci tylko klucz publiczny i wstrzyma klucz prywatny do odszyfrowywania.

Aby odszyfrować przy użyciu klucza prywatnego

  1. Kliknij przycisk Get Private Key. Etykieta wyświetla nazwę klucza i pokazuje, czy jest to pełna para kluczy.
  2. Decrypt File Kliknij przycisk i wybierz plik po prostu zaszyfrowany. To powiedzie się, ponieważ masz pełną parę kluczy do odszyfrowywania.

Zobacz też