逐步解說:建立密碼編譯應用程式

注意

本文適用於 Windows。

如需 ASP.NET Core的相關資訊,請參閱資料保護 ASP.NET Core

本逐步解說示範如何加密和解密檔案的內容。 程式碼範例是針對 Windows Form 應用程式所設計。 此應用程式不會示範真實世界案例,例如使用智慧卡。 相反地,它會示範加密和解密的基本概念。

本逐步解說針對加密使用下列指導方針:

  • 使用 Aes 類別 (一個對稱算法) 來加密和解密資料,使用其自動產生的 KeyIV

  • 使用 RSA 非對稱式演算法,加密和解密由 Aes 加密之資料的金鑰。 非對稱演算法最適合用於較少量的資料,例如金鑰。

    注意

    如果您想要保護電腦上的資料,而不與其他人交換加密的內容,請考慮使用 ProtectedData 類別。

下表摘要說明本主題中的密碼編譯工作。

Task 描述
建立 Windows Forms 應用程式 列出執行應用程式所需的控制項。
宣告全域物件 宣告字串路徑變數、CspParameters,和 RSACryptoServiceProvider 以擁有 Form 類別的全域內容。
建立非對稱金鑰 建立非對稱公開和私密金鑰值組,並對其指派金鑰容器名稱。
加密檔案 顯示對話方塊以選取要加密的檔案,並且進行加密。
解密檔案 顯示對話方塊以選取要解密的已加密檔案,並且進行解密。
取得私密金鑰 使用金鑰容器名稱取得完整金鑰組。
匯出公開金鑰 將金鑰儲存至僅包含公用參數的 XML 檔案。
匯入公開金鑰 將金鑰從 XML 檔案載入到金鑰容器。
測試應用程式 列出測試此應用程式的程序。

必要條件

您需要下列元件才能完成這個逐步解說:

建立 Windows Forms 應用程式

在此逐步解說中的大部分程式碼範例,已設計為按鈕控制項的事件處理常式。 下表列出範例應用程式所需的控制項,及其必要名稱以符合程式碼範例。

控制 名稱 文字屬性 (如有需要)
Button buttonEncryptFile 加密檔案
Button buttonDecryptFile 解密檔案
Button buttonCreateAsmKeys 建立金鑰
Button buttonExportPublicKey 匯出公開金鑰
Button buttonImportPublicKey 匯入公開金鑰
Button buttonGetPrivateKey 取得私密金鑰
Label label1 未設定金鑰
OpenFileDialog _encryptOpenFileDialog
OpenFileDialog _decryptOpenFileDialog

按兩下 Visual Studio 設計工具中的按鈕,來建立其事件處理常式。

宣告全域物件

將下列程式碼新增為 Form1 類別宣告的一部分。 針對您的環境和喜好設定編輯字串變數。

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

建立非對稱金鑰

此工作會建立非對稱金鑰來加密及解密 Aes 金鑰。 這個金鑰用來加密內容,且它會在標籤控制項上顯示金鑰容器名稱。

加入下列程式碼做為 Create Keys 按鈕的 Click 事件處理常式 (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

加密檔案

這項工作需要兩個方法:Encrypt File 按鈕的事件處理常式方法 (buttonEncryptFile_Click) 和 EncryptFile 方法。 第一種方法會顯示一個對話方塊來選取檔案,並將檔案名稱傳遞給第二個方法,後者則會執行加密。

加密的內容、金鑰和 IV 全都儲存到一個 FileStream,稱為加密套件。

EncryptFile 方法會執行下列動作:

  1. 建立 Aes 對稱演算法來加密內容。
  2. 建立 RSACryptoServiceProvider 物件來加密 Aes 金鑰。
  3. 使用 CryptoStream 物件以讀取及加密原始程式檔的 FileStream (以位元組區塊為單位) 成為加密檔案的目的地 FileStream 物件。
  4. 判斷加密金鑰和 IV 的長度,並建立其長度值的位元組陣列。
  5. 將金鑰、IV 和其長度值寫入加密套件。

加密套件使用下列格式:

  • 金鑰長度,位元組 0 - 3
  • IV 長度,位元組 4 - 7
  • 加密的金鑰
  • IV
  • 加密文字

您可以使用金鑰和 IV 的長度來決定加密套件所有部分的起始點和長度,這些可以用來解密檔案。

加入下列程式碼做為 Encrypt File 按鈕的 Click 事件處理常式 (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

將下列 EncryptFile 方法加入表單。

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

解密檔案

這項工作需要兩個方法:Decrypt File 按鈕的事件處理常式方法 (buttonDecryptFile_Click) 和 DecryptFile 方法。 第一種方法會顯示一個對話方塊來選取檔案,並將其檔案名稱傳遞給第二個方法,後者則會執行解密。

Decrypt 方法會執行下列動作:

  1. 建立 Aes 對稱演算法來解密內容。
  2. 讀取加密套件的 FileStream 前八個位元組到位元組陣列,以取得加密金鑰和 IV 的長度。
  3. 從加密套件將金鑰和 IV 擷取到位元組陣列。
  4. 建立 RSACryptoServiceProvider 物件來解密 Aes 金鑰。
  5. 使用 CryptoStream 物件以讀取及解密 FileStream 加密套件的加密文字區段 (以位元組區域為單位 ) 到解密檔案的 FileStream 物件。 完成後,就會解密完成。

加入下列程式碼做為 Decrypt File 按鈕的 Click 事件處理常式。

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

將下列 DecryptFile 方法加入表單。

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

匯出公開金鑰

這項工作會將 Create Keys 按鈕所建立的金鑰儲存到檔案。 它只會匯出公用參數。

這項工作模擬的案例是 Alice 提供給 Bob 她的公開金鑰,讓他可以為她加密檔案。 他和其他擁有該公開金鑰的使用者將無法解密這些檔案,因為他們沒有具私密參數的完整金鑰組。

加入下列程式碼做為 Export Public Key 按鈕的 Click 事件處理常式 (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

匯入公開金鑰

這項工作載入金鑰時只會附帶公用參數,如 Export Public Key 按鈕所建立,然後將它設定為金鑰容器名稱。

這項工作模擬的案例是 Bob 載入 Alice 的金鑰且僅包含公用參數,讓他可以為她加密檔案。

加入下列程式碼做為 Import Public Key 按鈕的 Click 事件處理常式 (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

取得私密金鑰

這項工作會將金鑰容器名稱設為使用 Create Keys 按鈕所建立的金鑰名稱。 金鑰容器將會包含完整金鑰組和私密參數。

這項工作模擬的案例是 Alice 使用她的私密金鑰來解密 Bob 所加密的檔案。

加入下列程式碼做為 Get Private Key 按鈕的 Click 事件處理常式 (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

測試應用程式

建立應用程式之後,請執行下列測試案例。

建立金鑰、加密和解密

  1. 按一下 Create Keys 按鈕。 標籤會顯示金鑰名稱,並顯示它是完整金鑰組。
  2. 按一下 Export Public Key 按鈕。 請注意匯出公開金鑰參數時,不會變更目前的金鑰。
  3. 按一下 Encrypt File 按鈕,然後選取檔案。
  4. 按一下 Decrypt File 按鈕,然後選取剛才加密的檔案。
  5. 檢查剛才解密的檔案。
  6. 關閉應用程式,然後重新啟動,以便在下一個案例中測試擷取保存的金鑰容器。

使用公開金鑰加密

  1. 按一下 Import Public Key 按鈕。 標籤會顯示金鑰名稱,並顯示它只是公開金鑰。
  2. 按一下 Encrypt File 按鈕,然後選取檔案。
  3. 按一下 Decrypt File 按鈕,然後選取剛才加密的檔案。 這將會失敗,因為您必須擁有私密金鑰才能解密。

這個案例示範了只具有公用金鑰來為另一個人加密檔案。 通常那個人只會提供您公開金鑰,並且保留私密金鑰來進行解密。

使用私密金鑰解密

  1. 按一下 Get Private Key 按鈕。 標籤會顯示金鑰名稱,並顯示它是否為完整金鑰組。
  2. 按一下 Decrypt File 按鈕,然後選取剛才加密的檔案。 這將會成功,因為您有完整金鑰組可以解密。

另請參閱