Almacenamiento de claves asimétricas en un contenedor de claves
Las claves privadas asimétricas nunca deben almacenarse literalmente o en texto sin formato en el equipo local. Si tiene que almacenar una clave privada, utilice un contenedor de claves. Para más información sobre contenedores de claves, consulte Descripción de los contenedores de claves RSA en el nivel de equipo y de usuario.
Nota
El código de este artículo se aplica a Windows y usa características que no están disponibles en .NET Core 2.2 y versiones anteriores. Para más información, consulte la incidencia 23391 de dotnet/runtime.
Creación de una clave asimétrica y almacenamiento en un contenedor de claves
Cree una instancia nueva de una clase CspParameters y pase el nombre que quiera darle al contenedor de claves al campo CspParameters.KeyContainerName.
Cree una nueva instancia de una clase que se deriva de la clase AsymmetricAlgorithm (normalmente RSACryptoServiceProvider o DSACryptoServiceProvider) y pase el objeto
CspParameters
previamente creado a su constructor.
Nota
La creación y recuperación de una clave asimétrica es una operación. Si una clave aún no está en el contenedor, se creará antes de devolverse.
Eliminación de la clave del contenedor de claves
Cree una instancia nueva de una clase
CspParameters
y pase el nombre que quiera darle al contenedor de claves al campo CspParameters.KeyContainerName.Cree una nueva instancia de una clase que se deriva de la clase AsymmetricAlgorithm (normalmente
RSACryptoServiceProvider
oDSACryptoServiceProvider
) y pase el objetoCspParameters
previamente creado a su constructor.Establezca la propiedad RSACryptoServiceProvider.PersistKeyInCsp o la propiedad DSACryptoServiceProvider.PersistKeyInCsp de la clase que se deriva de
AsymmetricAlgorithm
afalse
(False
en Visual Basic).Llame al método
Clear
de la clase que se deriva deAsymmetricAlgorithm
. Este método libera todos los recursos de la clase y borra el contenedor de claves.
Ejemplo
En el ejemplo siguiente se muestra cómo crear una clave asimétrica, guardarla en un contenedor de claves, recuperarla posteriormente y eliminarla del contenedor.
Observe que el código de los métodos GenKey_SaveInContainer
y GetKeyFromContainer
es similar. Si especifica el nombre de un contenedor de claves para un objeto CspParameters y lo pasa a un objeto AsymmetricAlgorithm con la propiedad PersistKeyInCsp o la propiedad PersistKeyInCsp establecidas en true
, el comportamiento será el siguiente:
- Si no existe un contenedor de claves con el nombre especificado, se crea uno y la clave se conserva.
- Si no existe un contenedor de claves con el nombre especificado, la clave del contenedor se carga automáticamente en el objeto AsymmetricAlgorithm actual.
Por lo tanto, el código del método GenKey_SaveInContainer
conserva la clave porque se ejecuta primero, mientras que el código del método GetKeyFromContainer
carga la clave porque se ejecuta en 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.");
}
}
La salida es como sigue:
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.