Przechowywanie kluczy asymetrycznych w kontenerze kluczy

Asymetryczne klucze prywatne nigdy nie powinny być przechowywane dosłownie ani w postaci zwykłego tekstu na komputerze lokalnym. Jeśli musisz przechowywać klucz prywatny, użyj kontenera kluczy. Aby uzyskać więcej informacji na temat kontenerów kluczy, zobacz Opis kontenerów kluczy RSA na poziomie maszyny i na poziomie użytkownika.

Uwaga

Kod w tym artykule dotyczy systemu Windows i używa funkcji, które nie są dostępne na platformie .NET Core 2.2 i starszych wersjach. Aby uzyskać więcej informacji, zobacz dotnet/runtime#23391.

Tworzenie klucza asymetrycznego i zapisywanie go w kontenerze kluczy

  1. Utwórz nowe wystąpienie CspParameters klasy i przekaż nazwę, którą chcesz wywołać kontener kluczy do CspParameters.KeyContainerName pola.

  2. Utwórz nowe wystąpienie klasy pochodzącej z AsymmetricAlgorithm klasy (zwykle RSACryptoServiceProvider lub DSACryptoServiceProvider) i przekaż wcześniej utworzony CspParameters obiekt do konstruktora.

Uwaga

Tworzenie i pobieranie klucza asymetrycznego to jedna operacja. Jeśli klucz nie znajduje się jeszcze w kontenerze, zostanie utworzony przed zwróceniem.

Usuwanie klucza z kontenera kluczy

  1. Utwórz nowe wystąpienie CspParameters klasy i przekaż nazwę, którą chcesz wywołać kontener kluczy do CspParameters.KeyContainerName pola.

  2. Utwórz nowe wystąpienie klasy pochodzącej z AsymmetricAlgorithm klasy (zwykle RSACryptoServiceProvider lub DSACryptoServiceProvider) i przekaż wcześniej utworzony CspParameters obiekt do konstruktora.

  3. RSACryptoServiceProvider.PersistKeyInCsp Ustaw właściwość lub DSACryptoServiceProvider.PersistKeyInCsp klasy pochodzącej z AsymmetricAlgorithm klasy na false (False w Visual Basic).

  4. Wywołaj metodę Clear klasy, która pochodzi z klasy AsymmetricAlgorithm. Ta metoda zwalnia wszystkie zasoby klasy i czyści kontener kluczy.

Przykład

W poniższym przykładzie pokazano, jak utworzyć klucz asymetryczny, zapisać go w kontenerze kluczy, pobrać klucz w późniejszym czasie i usunąć klucz z kontenera.

Zwróć uwagę, że kod w metodzie GenKey_SaveInContainer i metodzie GetKeyFromContainer jest podobny. Po określeniu nazwy kontenera klucza dla CspParameters obiektu i przekazaniu go do AsymmetricAlgorithm obiektu z PersistKeyInCsp właściwością lub PersistKeyInCsp właściwością ustawioną na true, zachowanie jest następujące:

  • Jeśli kontener kluczy o określonej nazwie nie istnieje, zostanie utworzony, a klucz zostanie utrwalone.
  • Jeśli kontener kluczy o określonej nazwie istnieje, klucz w kontenerze zostanie automatycznie załadowany do bieżącego AsymmetricAlgorithm obiektu.

W związku z tym kod w metodzie GenKey_SaveInContainer utrwala klucz, ponieważ jest uruchamiany jako pierwszy, podczas gdy kod w GetKeyFromContainer metodzie ładuje klucz, ponieważ jest uruchamiany w sekundzie.

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

Wynik jest następujący:

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.

Zobacz też