将非对称密钥存储在密钥容器中

非对称私钥永远不应以原义或纯文本形式存储在本地计算机上。 如果需要存储私钥,可以使用密钥容器。 有关密钥容器的详细信息,请参阅了解计算机级别和用户级别的 RSA 密钥容器

注意

本文中的代码适用于 Windows,并使用了 .NET Core 2.2 及更早版本中没有的功能。 有关详细信息,请参阅 dotnet/runtime#23391

创建非对称密钥并将其保存在密钥容器中

  1. 创建 CspParameters 类的一个新实例,并将你要调用密钥容器的名称传递给 CspParameters.KeyContainerName 字段。

  2. 创建一个派生自 AsymmetricAlgorithm 类(通常是 RSACryptoServiceProviderDSACryptoServiceProvider)的类的新实例,并将先前创建的 CspParameters 对象传递给其构造函数。

注意

创建和检索非对称密钥是一项操作。 如果容器中还没有密钥,在返回之前就会创建。

从密钥容器中删除密钥

  1. 创建 CspParameters 类的一个新实例,并将你要调用密钥容器的名称传递给 CspParameters.KeyContainerName 字段。

  2. 创建一个派生自 AsymmetricAlgorithm 类(通常是 RSACryptoServiceProviderDSACryptoServiceProvider)的类的新实例,并将先前创建的 CspParameters 对象传递给其构造函数。

  3. 将派生自 AsymmetricAlgorithm 的类的 RSACryptoServiceProvider.PersistKeyInCspDSACryptoServiceProvider.PersistKeyInCsp 属性设置为 false(在 Visual Basic 中为 False)。

  4. 调用派生自 AsymmetricAlgorithm 的类的 Clear 方法。 该方法释放该类所有的资源并清除密钥容器。

示例

下面的示例说明下面这一过程:创建一个非对称密钥,将其保存在密钥容器中,以后检索此密钥,最后从该容器中删除此密钥。

请注意,GenKey_SaveInContainer 方法和 GetKeyFromContainer 方法的代码相似。 当为 CspParameters 对象指定密钥容器名称并将其传递给 PersistKeyInCsp 属性或 PersistKeyInCsp 属性设置为 trueAsymmetricAlgorithm 对象时,行为如下:

  • 如果附带指定名称的密钥容器不存在,那么将创建一个并且该密钥保持不变。
  • 如果确实存在具有指定名称的密钥容器,则将此容器中的密钥自动加载到当前 AsymmetricAlgorithm 对象中。

因此,GenKey_SaveInContainer 方法中的代码保持密钥不变,因为它首先运行;而 GetKeyFromContainer 方法中的代码加载此密钥,因为它随后运行。

Imports System
Imports System.Security.Cryptography

Public Class StoreKey

    Public Shared Sub Main()
        Try
            ' Create a key and save it in a container.
            GenKey_SaveInContainer("MyKeyContainer")

            ' Retrieve the key from the container.
            GetKeyFromContainer("MyKeyContainer")

            ' Delete the key from the container.
            DeleteKeyFromContainer("MyKeyContainer")

            ' Create a key and save it in a container.
            GenKey_SaveInContainer("MyKeyContainer")

            ' Delete the key from the container.
            DeleteKeyFromContainer("MyKeyContainer")
        Catch e As CryptographicException
            Console.WriteLine(e.Message)
        End Try
    End Sub

    Private Shared Sub GenKey_SaveInContainer(ByVal ContainerName As String)
        ' Create the CspParameters object and set the key container
        ' name used to store the RSA key pair.
        Dim parameters As New CspParameters With {
            .KeyContainerName = ContainerName
        }

        ' Create a new instance of RSACryptoServiceProvider that accesses
        ' the key container MyKeyContainerName.
        Using rsa As New RSACryptoServiceProvider(parameters)
            ' Display the key information to the console.
            Console.WriteLine($"Key added to container:  {rsa.ToXmlString(True)}")
        End Using
    End Sub

    Private Shared Sub GetKeyFromContainer(ByVal ContainerName As String)
        ' Create the CspParameters object and set the key container
        '  name used to store the RSA key pair.
        Dim parameters As New CspParameters With {
            .KeyContainerName = ContainerName
        }

        ' Create a new instance of RSACryptoServiceProvider that accesses
        ' the key container MyKeyContainerName.
        Using rsa As New RSACryptoServiceProvider(parameters)
            ' Display the key information to the console.
            Console.WriteLine($"Key retrieved from container : {rsa.ToXmlString(True)}")
        End Using
    End Sub

    Private Shared Sub DeleteKeyFromContainer(ByVal ContainerName As String)
        ' Create the CspParameters object and set the key container
        '  name used to store the RSA key pair.
        Dim parameters As New CspParameters With {
            .KeyContainerName = ContainerName
        }

        ' Create a new instance of RSACryptoServiceProvider that accesses
        ' the key container.
        ' Delete the key entry in the container.
        Dim rsa As New RSACryptoServiceProvider(parameters) With {
            .PersistKeyInCsp = False
        }

        ' Call Clear to release resources and delete the key from the container.
        rsa.Clear()

        Console.WriteLine("Key deleted.")
    End Sub
End Class
using System;
using System.Security.Cryptography;

public class StoreKey
{
    public static void Main()
    {
        try
        {
            // Create a key and save it in a container.
            GenKey_SaveInContainer("MyKeyContainer");

            // Retrieve the key from the container.
            GetKeyFromContainer("MyKeyContainer");

            // Delete the key from the container.
            DeleteKeyFromContainer("MyKeyContainer");

            // Create a key and save it in a container.
            GenKey_SaveInContainer("MyKeyContainer");

            // Delete the key from the container.
            DeleteKeyFromContainer("MyKeyContainer");
        }
        catch (CryptographicException e)
        {
            Console.WriteLine(e.Message);
        }
    }

    private static void GenKey_SaveInContainer(string containerName)
    {
        // Create the CspParameters object and set the key container
        // name used to store the RSA key pair.
        var parameters = new CspParameters
        {
            KeyContainerName = containerName
        };

        // Create a new instance of RSACryptoServiceProvider that accesses
        // the key container MyKeyContainerName.
        using var rsa = new RSACryptoServiceProvider(parameters);

        // Display the key information to the console.
        Console.WriteLine($"Key added to container: \n  {rsa.ToXmlString(true)}");
    }

    private static void GetKeyFromContainer(string containerName)
    {
        // Create the CspParameters object and set the key container
        // name used to store the RSA key pair.
        var parameters = new CspParameters
        {
            KeyContainerName = containerName
        };

        // Create a new instance of RSACryptoServiceProvider that accesses
        // the key container MyKeyContainerName.
        using var rsa = new RSACryptoServiceProvider(parameters);

        // Display the key information to the console.
        Console.WriteLine($"Key retrieved from container : \n {rsa.ToXmlString(true)}");
    }

    private static void DeleteKeyFromContainer(string containerName)
    {
        // Create the CspParameters object and set the key container
        // name used to store the RSA key pair.
        var parameters = new CspParameters
        {
            KeyContainerName = containerName
        };

        // Create a new instance of RSACryptoServiceProvider that accesses
        // the key container.
        using var rsa = new RSACryptoServiceProvider(parameters)
        {
            // Delete the key entry in the container.
            PersistKeyInCsp = false
        };

        // Call Clear to release resources and delete the key from the container.
        rsa.Clear();

        Console.WriteLine("Key deleted.");
    }
}

输出如下所示:

Key added to container:
<RSAKeyValue> Key Information A</RSAKeyValue>
Key retrieved from container :
<RSAKeyValue> Key Information A</RSAKeyValue>
Key deleted.
Key added to container:
<RSAKeyValue> Key Information B</RSAKeyValue>
Key deleted.

另请参阅