Armazenar chaves assimétricas em um contêiner de chaves

As chaves privadas assimétricas nunca devem ser armazenadas no formato textual nem como texto sem formatação no computador local. Se você precisar armazenar uma chave privada, use um contêiner de chave. Para obter mais informações sobre contêineres de chave, consulte Noções básicas sobre contêineres de chave RSA em nível de máquina e de usuário.

Observação

O código neste artigo se aplica ao Windows e usa recursos não disponíveis no .NET Core 2.2 e em versões anteriores. Para obter mais informações, consulte dotnet/runtime#23391.

Crie uma chave assimétrica e salve-a em um contêiner de chave

  1. Crie uma nova instância de uma classe CspParameters e passe o nome que você deseja chamar o contêiner de chave para o campo CspParameters.KeyContainerName.

  2. Crie uma nova instância de uma classe que deriva da classe AsymmetricAlgorithm (geralmente RSACryptoServiceProvider ou DSACryptoServiceProvider) e passe o objeto CspParameters criado anteriormente para seu construtor.

Observação

A criação e recuperação de uma chave assimétrica é uma operação. Se uma chave ainda não estiver no contêiner, ela será criada antes de ser retornada.

Excluir a chave do contêiner de chaves

  1. Crie uma nova instância de uma classe CspParameters e passe o nome que você deseja chamar o contêiner de chave para o campo CspParameters.KeyContainerName.

  2. Crie uma nova instância de uma classe que deriva da classe AsymmetricAlgorithm (geralmente RSACryptoServiceProvider ou DSACryptoServiceProvider) e passe o objeto CspParameters criado anteriormente para seu construtor.

  3. Defina a propriedade RSACryptoServiceProvider.PersistKeyInCsp ou DSACryptoServiceProvider.PersistKeyInCsp da classe que deriva de AsymmetricAlgorithm para false (False no Visual Basic).

  4. Chame o método Clear da classe que deriva de AsymmetricAlgorithm. Esse método libera todos os recursos da classe e limpa o contêiner de chaves.

Exemplo

O exemplo a seguir mostra como criar uma chave assimétrica, salvá-la em um contêiner de chaves, recuperar a chave posteriormente e excluir a chave do contêiner.

Observe que o código no método GenKey_SaveInContainer e no método GetKeyFromContainer é semelhante. Quando você especifica um nome de contêiner de chave para um objeto CspParameters e o passa para um objeto AsymmetricAlgorithm com a propriedade PersistKeyInCsp ou a propriedade PersistKeyInCsp definida como true, o comportamento é o seguinte:

  • se o contêiner de chaves com o nome especificado não existir, ele será criado e a chave persistirá.
  • Se o contêiner de chaves com o nome especificado existir, a chave será carregada automaticamente no objeto AsymmetricAlgorithm atual.

Portanto, o código no método GenKey_SaveInContainer mantém a chave porque é executado primeiro, enquanto o código no método GetKeyFromContainer carrega a chave porque é executado em segundo lugar.

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

A saída é da seguinte maneira:

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.

Confira também