Hacher les mots de passe dans ASP.NET Core

Cet article explique comment appeler la méthode KeyDerivation.Pbkdf2 qui permet de hacher un mot de passe à l’aide de l’algorithme PBKDF2.

Avertissement

L’API KeyDerivation.Pbkdf2 est une primitive de chiffrement de bas niveau qui est destinée à servir pour l’intégration des applications dans un protocole ou un système de chiffrement existant. KeyDerivation.Pbkdf2 ne doit pas être utilisé dans les nouvelles applications qui prennent en charge la connexion par mot de passe et doivent stocker les mots de passe hachés dans un magasin de données. Les nouvelles applications doivent utiliser PasswordHasher. Pour plus d’informations sur PasswordHasher, consultez Exploration du ASP.NET Core Identity PasswordHasher.

La base du code de la protection des données comprend un package NuGet Microsoft.AspNetCore.Cryptography.KeyDerivation qui contient des fonctions de dérivation de clé de chiffrement. Ce package est un composant autonome sans dépendance sur le reste du système de protection des données. Il peut être utilisé séparément. La source existe à côté de la base du code de la protection des données pour des raisons pratiques.

Avertissement

Le code suivant montre comment utiliser KeyDerivation.Pbkdf2 pour générer une clé secrète partagée. Il ne doit pas être utilisé pour hacher un mot de passe afin de le stocker dans un magasin de données.

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

Consultez le code source du type PasswordHasher d’ASP.NET Core Identity pour un cas d’usage réel.

Notes

Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).