Contraseñas hash en ASP.NET Core

En este artículo se muestra cómo llamar al método KeyDerivation.Pbkdf2 , que permite aplicar un hash a una contraseña con el algoritmo PBKDF2, como se describe en RFC 2898, Sección 5.2.

La KeyDerivation.Pbkdf2 API es un primitivo criptográfico de bajo nivel. El uso previsto es integrar aplicaciones en un protocolo o sistema criptográfico existente.

Advertencia

KeyDerivation.Pbkdf2 no debe usarse en nuevas aplicaciones que admitan el inicio de sesión basado en contraseña y que necesiten almacenar contraseñas con hash en un almacén de datos. Las nuevas aplicaciones deben usar la clase PasswordHasher . Para obtener más información, vea Exploring the ASP.NET Core Identity PasswordHasher.

La base de código de protección de datos incluye un paquete NuGet Microsoft. AspNetCore.Cryptography.KeyDerivation que contiene funciones de derivación de claves criptográficas. Este paquete es un componente independiente y no tiene dependencias en el resto del sistema de protección de datos. El paquete se puede usar de forma independiente. El código fuente existe junto al código base de protección de datos para mayor comodidad.

Generar clave con 'KeyDerivation.Pbkdf2'

En el código siguiente se muestra cómo usar el KeyDerivation.Pbkdf2 método para generar una clave secreta compartida.

Advertencia

No llame al método KeyDerivation.Pbkdf2 para calcular el hash de una contraseña para almacenarla en una base de datos.

using Microsoft.AspNetCore.Cryptography.KeyDerivation;
using System.Security.Cryptography;

Console.Write("Enter a password: ");
string? password = Console.ReadLine();

// Generate a 128-bit salt using a sequence of
// cryptographically strong random bytes.
byte[] salt = RandomNumberGenerator.GetBytes(128 / 8); // divide by 8 to convert bits to bytes
Console.WriteLine($"Salt: {Convert.ToBase64String(salt)}");

// derive a 256-bit subkey (use HMACSHA256 with 100,000 iterations)
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
    password: password!,
    salt: salt,
    prf: KeyDerivationPrf.HMACSHA256,
    iterationCount: 100000,
    numBytesRequested: 256 / 8));

Console.WriteLine($"Hashed: {hashed}");

/*
 * SAMPLE OUTPUT
 *
 * Enter a password: Xtw9NMgx
 * Salt: CGYzqeN4plZekNC88Umm1Q==
 * Hashed: Gt9Yc4AiIvmsC1QQbe2RZsCIqvoYlst2xbz0Fs8aHnw=
 */
using System;
using System.Security.Cryptography;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;

public class Program
{
    public static void Main(string[] args)
    {
        Console.Write("Enter a password: ");
        string password = Console.ReadLine();

        // generate a 128-bit salt using a cryptographically strong random sequence of nonzero values
        byte[] salt = new byte[128 / 8];
        using (var rngCsp = new RNGCryptoServiceProvider())
        {
            rngCsp.GetNonZeroBytes(salt);
        }
        Console.WriteLine($"Salt: {Convert.ToBase64String(salt)}");

        // derive a 256-bit subkey (use HMACSHA256 with 100,000 iterations)
        string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
            password: password,
            salt: salt,
            prf: KeyDerivationPrf.HMACSHA256,
            iterationCount: 100000,
            numBytesRequested: 256 / 8));
        Console.WriteLine($"Hashed: {hashed}");
    }
}

/*
 * SAMPLE OUTPUT
 *
 * Enter a password: Xtw9NMgx
 * Salt: CGYzqeN4plZekNC88Umm1Q==
 * Hashed: Gt9Yc4AiIvmsC1QQbe2RZsCIqvoYlst2xbz0Fs8aHnw=
 */
 

Para obtener un caso de uso real del tipo ASP.NET Core IdentityPasswordHasher, vea el código source en GitHub.

Nota

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, usa la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, vea Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).