EDIT: As pointed out by @MikeT, the original link and code I posted is no longer considered best practice for hashing passwords to be stored in a datastore.
This article by Scott Brady illustrates how to use PasswordHasher, and also how to use the interface to develop stronger hashing implementations.
So applying the byte-level hashing function yourself is not required any more, but it you want to see how it's done this article explores the PasswordHasher<T> implementation:
Exploring the ASP.NET Core Identity PasswordHasher
A relevant piece of code from the article is shown below:
private static byte[] HashPasswordV2(string password, RandomNumberGenerator rng) { const KeyDerivationPrf Pbkdf2Prf = KeyDerivationPrf.HMACSHA1; // default for Rfc2898DeriveBytes const int Pbkdf2IterCount = 1000; // default for Rfc2898DeriveBytes const int Pbkdf2SubkeyLength = 256 / 8; // 256 bits const int SaltSize = 128 / 8; // 128 bits // Produce a version 2 text hash. byte[] salt = new byte[SaltSize]; rng.GetBytes(salt); byte[] subkey = KeyDerivation.Pbkdf2(password, salt, Pbkdf2Prf, Pbkdf2IterCount, Pbkdf2SubkeyLength); var outputBytes = new byte[1 + SaltSize + Pbkdf2SubkeyLength]; outputBytes[0] = 0x00; // format marker Buffer.BlockCopy(salt, 0, outputBytes, 1, SaltSize); Buffer.BlockCopy(subkey, 0, outputBytes, 1 + SaltSize, Pbkdf2SubkeyLength); return outputBytes; }
Original answer:
Microsoft has a page up with sample code using PBKDF2 for anyone using .Net Core:
Hash passwords in ASP.NET Core
From the article:
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 secure PRNG byte[] salt = new byte[128 / 8]; using (var rng = RandomNumberGenerator.Create()) { rng.GetBytes(salt); } Console.WriteLine($"Salt: {Convert.ToBase64String(salt)}"); // derive a 256-bit subkey (use HMACSHA1 with 10,000 iterations) string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2( password: password, salt: salt, prf: KeyDerivationPrf.HMACSHA1, iterationCount: 10000, numBytesRequested: 256 / 8)); Console.WriteLine($"Hashed: {hashed}"); } } /* * SAMPLE OUTPUT * * Enter a password: Xtw9NMgx * Salt: NZsP6NnmfBuYeJrrAKNuVQ== * Hashed: /OOoOer10+tGwTRDTrQSoeCxVTFr6dtYly7d0cPxIak= */
hash passwords salt .netyou'll get lots of appropriate hits.