Хранение асимметричных ключей в контейнере ключей

Асимметричные закрытые ключи никогда не следует хранить буквальной форме или в формате обычного текста на локальном компьютере. Если необходимо сохранить закрытый ключ, используйте контейнер ключей. Дополнительные сведения о контейнерах ключей см. в разделе "Общие сведения о контейнерах ключей RSA на уровне компьютера и пользователя".

Примечание.

Код, приведенный в этой статье, применяется к Windows и использует функции, недоступные в .NET Core 2.2 и более ранних версиях. Дополнительные сведения см. в статье dotnet/runtime#23391.

Создание асимметричного ключа и его сохранение в контейнере ключей

  1. Создайте новый экземпляр CspParameters класса и передайте имя, которое необходимо вызвать в поле контейнера ключей CspParameters.KeyContainerName .

  2. Создайте новый экземпляр класса, наследуемого от AsymmetricAlgorithm класса (обычно RSACryptoServiceProvider или DSACryptoServiceProvider) и передайте ранее созданный CspParameters объект в его конструктор.

Примечание.

Создание и извлечение асимметричного ключа является одной операцией. Если ключ еще не находится в контейнере, он создается перед возвратом.

Удаление ключа из контейнера ключей

  1. Создайте новый экземпляр CspParameters класса и передайте имя, которое необходимо вызвать в поле контейнера ключей CspParameters.KeyContainerName .

  2. Создайте новый экземпляр класса, наследуемого от AsymmetricAlgorithm класса (обычно RSACryptoServiceProvider или DSACryptoServiceProvider) и передайте ранее созданный CspParameters объект в его конструктор.

  3. RSACryptoServiceProvider.PersistKeyInCsp Задайте или DSACryptoServiceProvider.PersistKeyInCsp свойство класса, наследуемого от AsymmetricAlgorithmfalse (Falseв Visual Basic).

  4. Clear Вызовите метод класса, наследуемого от AsymmetricAlgorithm. Этот метод освобождает все ресурсы класса и очищает контейнер ключей.

Пример

В следующем примере показано, как создать асимметричный ключ, сохранить его в контейнере ключей, затем извлечь ключ и удалить его из контейнера.

Обратите внимание, что код в методах GenKey_SaveInContainer и GetKeyFromContainer совпадает. Если указать имя контейнера ключа для CspParameters объекта и передать его AsymmetricAlgorithm объекту со PersistKeyInCsp свойством или PersistKeyInCsp свойством, заданным trueв , поведение выглядит следующим образом:

  • Если контейнер ключей с указанным именем не существует, он создается, а ключ сохраняется.
  • Если контейнер ключей с указанным именем существует, то ключ в этом контейнере автоматически загружается в текущий объект AsymmetricAlgorithm.

Поэтому код в методе сохраняет ключ, так как он выполняется первым, а код в GenKey_SaveInContainerGetKeyFromContainer методе загружает ключ, так как он выполняется второй.

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.

См. также