Хэш-пароли в ASP.NET Core

В этой статье показано, как вызвать KeyDerivation.Pbkdf2 метод, позволяющий хэшировать пароль с помощью алгоритма PBKDF2.

Предупреждение

KeyDerivation.Pbkdf2 API является низкоуровневым примитивом шифрования и предназначен для интеграции приложений в существующую протокол или криптографическую систему. KeyDerivation.Pbkdf2 не следует использовать в новых приложениях, которые поддерживают вход на основе паролей и должны хранить хэшированные пароли в хранилище данных. Новые приложения должны использовать PasswordHasher. Дополнительные сведения PasswordHasherсм. в статье "Изучение ASP.NET Core Identity PasswordHasher".

База кода защиты данных включает пакет NuGet Microsoft.AspNetCore.Cryptography.KeyDerivation , содержащий функции производного ключа шифрования. Этот пакет является автономным компонентом и не имеет зависимостей от rest системы защиты данных. Его можно использовать независимо. Источник существует вместе с базой кода защиты данных в качестве удобства.

Предупреждение

В следующем коде показано, как создать KeyDerivation.Pbkdf2 общий секретный ключ. Он не должен использоваться для хэшировать пароль для хранения в хранилище данных.

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=
 */
 

См. исходный код для типа ASP.NET Core IdentityPasswordHasher для реального варианта использования.

Примечание.

По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).