Proveedores de almacenamiento de claves en ASP.NET Core
El sistema de protección de datos emplea un mecanismo de detección de forma predeterminada para determinar dónde se deben conservar las claves criptográficas. El desarrollador puede invalidar el mecanismo de detección predeterminado y especificar manualmente la ubicación.
Advertencia
Si especifica una ubicación de persistencia de clave explícita, el sistema de protección de datos anula el registro del mecanismo de cifrado de claves en reposo predeterminado, por lo que las claves ya no se cifran en reposo. Se recomienda especificar además un mecanismo de cifrado de claves explícito para las implementaciones de producción.
Sistema de archivos
Para configurar un repositorio de claves basado en el sistema de archivos, llame a la rutina de configuración PersistKeysToFileSystem como se muestra a continuación. Proporcione un elemento DirectoryInfo que apunte al repositorio donde se deben almacenar las claves:
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"c:\temp-keys\"));
}
puede apuntar a un directorio en el equipo local o a una DirectoryInfo carpeta de un recurso compartido de red. Si apunta a un directorio en la máquina local (y el escenario es que solo las aplicaciones del equipo local requieren acceso para usar este repositorio), considere la posibilidad de usar DPAPI de Windows (en Windows) para cifrar las claves en reposo. De lo contrario, considere la posibilidad de usar un certificado X.509 para cifrar las claves en reposo.
Azure Storage
El paquete Azure.Extensions.AspNetCore.DataProtection.Blobs permite almacenar claves de protección de datos Azure Blob Storage. Las claves se pueden compartir entre varias instancias de una aplicación web. Las aplicaciones pueden compartir la cookie autenticación o la protección CSRF entre varios servidores.
Para configurar el Azure Blob Storage, llame a una de las sobrecargas persistKeysToAzureBlobStorage.
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection()
.PersistKeysToAzureBlobStorage(new Uri("<blob URI including SAS token>"));
}
Si la aplicación web se ejecuta como un servicio de Azure, se puede usar la cadena de conexión para autenticarse en Azure Storage mediante Azure.Storage.Blobs.
string connectionString = "<connection_string>";
string containerName = "my-key-container";
BlobContainerClient container = new BlobContainerClient(connectionString, containerName);
// optional - provision the container automatically
await container.CreateIfNotExistsAsync();
services.AddDataProtection()
.PersistKeysToAzureBlobStorage(container, "keys.xml");
Nota
La cadena de conexión a la cuenta de almacenamiento se puede encontrar en Azure Portal, en la sección "Claves de acceso" o mediante la ejecución del siguiente comando de la CLI:
az storage account show-connection-string --name <account_name> --resource-group <resource_group>
Redis
El paquete Microsoft.AspNetCore.DataProtection.StackExchangeRedis permite almacenar claves de protección de datos en una caché de Redis. Las claves se pueden compartir entre varias instancias de una aplicación web. Las aplicaciones pueden compartir la cookie autenticación o la protección CSRF entre varios servidores.
El paquete Microsoft.AspNetCore.DataProtection.Redis permite almacenar claves de protección de datos en una caché de Redis. Las claves se pueden compartir entre varias instancias de una aplicación web. Las aplicaciones pueden compartir la cookie autenticación o la protección CSRF entre varios servidores.
Para configurar en Redis, llame a una de las sobrecargas de PersistKeysToStackExchangeRedis:
public void ConfigureServices(IServiceCollection services)
{
var redis = ConnectionMultiplexer.Connect("<URI>");
services.AddDataProtection()
.PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");
}
Para configurar en Redis, llame a una de las sobrecargas de PersistKeysToRedis:
public void ConfigureServices(IServiceCollection services)
{
var redis = ConnectionMultiplexer.Connect("<URI>");
services.AddDataProtection()
.PersistKeysToRedis(redis, "DataProtection-Keys");
}
Para obtener más información, vea los temas siguientes:
- StackExchange.Redis ConnectionMultiplexer
- Azure Redis Cache
- ASP.NET ejemplos de DataProtection principal
Registro
Solo se aplica a las implementaciones de Windows.
A veces, es posible que la aplicación no tenga acceso de escritura al sistema de archivos. Considere un escenario en el que una aplicación se ejecuta como una cuenta de servicio virtual (por ejemplo,w3wp.exe identidad del grupo de aplicaciones). En estos casos, el administrador puede aprovisionar una clave del Registro a la que sea accesible la identidad de la cuenta de servicio. Llame al método de extensión PersistKeysToRegistry como se muestra a continuación. Proporcione una registryKey que apunte a la ubicación donde se deben almacenar las claves criptográficas:
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection()
.PersistKeysToRegistry(Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Sample\keys", true));
}
Importante
Se recomienda usar DPAPI de Windows para cifrar las claves en reposo.
Entity Framework Core
El paquete Microsoft.AspNetCore.DataProtection.EntityFrameworkCore proporciona un mecanismo para almacenar claves de protección de datos en una base de datos mediante Entity Framework Core. El paquete NuGet debe agregarse al archivo del proyecto, no forma parte del Microsoft.AspNetCore.DataProtection.EntityFrameworkCore metapaquete Microsoft.AspNetCore.App .
Con este paquete, las claves se pueden compartir entre varias instancias de una aplicación web.
Para configurar el proveedor EF Core, llame al método <TContext> PersistKeysToDbContext:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
// Add a DbContext to store your Database Keys
services.AddDbContext<MyKeysContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("MyKeysConnection")));
// using Microsoft.AspNetCore.DataProtection;
services.AddDataProtection()
.PersistKeysToDbContext<MyKeysContext>();
services.AddDefaultIdentity<IdentityUser>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
Si quiere que los comentarios de código se traduzcan en más idiomas además del inglés, háganoslo saber en este problema de debate de GitHub.
El parámetro genérico, TContext , debe heredar de DbContext e implementar IDataProtectionKeyContext:
using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using WebApp1.Data;
namespace WebApp1
{
class MyKeysContext : DbContext, IDataProtectionKeyContext
{
// A recommended constructor overload when using EF Core
// with dependency injection.
public MyKeysContext(DbContextOptions<MyKeysContext> options)
: base(options) { }
// This maps to the table that stores keys.
public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }
}
}
Cree la tabla DataProtectionKeys.
Ejecute los siguientes comandos en la ventana Administrador de paquetes Consola de administración (PMC):
Add-Migration AddDataProtectionKeys -Context MyKeysContext
Update-Database -Context MyKeysContext
MyKeysContext es el DbContext definido en el ejemplo de código anterior. Si usa un con un DbContext nombre diferente, sustituya su DbContext nombre por MyKeysContext .
La DataProtectionKeys clase o entidad adopta la estructura que se muestra en la tabla siguiente.
| Propiedad o campo | Tipo CLR | Tipo de SQL |
|---|---|---|
Id |
int |
int, PK, IDENTITY(1,1) , not null |
FriendlyName |
string |
nvarchar(MAX)Null |
Xml |
string |
nvarchar(MAX)Null |
Repositorio de claves personalizadas
Si los mecanismos de entrada no son adecuados, el desarrollador puede especificar su propio mecanismo de persistencia de clave proporcionando un IXmlRepository personalizado.