ASP.NET Core 3.1 - Hash and Verify Passwords with BCrypt
Tutorial built with ASP.NET Core 3.1
Other versions available:
This is a quick example of how to hash and verify passwords in ASP.NET Core 3.1 using the BCrypt.Net-Next
password hashing library which is a C# implementation of the bcrypt
password hashing function.
For more info on the BCrypt.Net-Next password hashing C# library see https://www.nuget.org/packages/BCrypt.Net-Next.
For more info on the underlying bcrypt password hashing function, see https://en.wikipedia.org/wiki/bcrypt.
Installing BCrypt.Net-Next via NuGet
.NET Core CLI: dotnet add package BCrypt.Net-Next
Visual Studio Package Manager Console: Install-Package BCrypt.Net-Next
Hashing a password in ASP.NET Core
This code hashes the password "Pa$$w0rd"
using bcrypt and stores the result in the passwordHash
string variable.
string passwordHash = BCrypt.Net.BCrypt.HashPassword("Pa$$w0rd");
Verify a password against a hash in ASP.NET Core
This code verifies the password "Pa$$w0rd"
using bcrypt against the hash stored in the passwordHash
variable.
bool verified = BCrypt.Net.BCrypt.Verify("Pa$$w0rd", passwordHash);
Example usage in an Account Service
Below is an example account service with a Register()
method that saves an account with a hashed password and an Authenticate()
method that verifies a provided password against the PasswordHash
of a saved account.
The service is a simplified version of the account service from a boilerplate api project I posted recently, for more info and to test out the service in a fully functioning project see ASP.NET Core 3.1 - Boilerplate API with Email Sign Up, Verification, Authentication & Forgot Password.
One small thing to note is the using alias directive on the first line (using BC = BCrypt.Net.BCrypt;
). This is required to avoid having to use the full path to the class when calling a BCrypt method (e.g. BCrypt.Net.BCrypt.HashPassword()
) because the namespace and the class name are both the same (BCrypt
). Another way around this is to move the using statement using BCrypt.Net;
inside the namespace (namespace WebApi.Services
) which would allow you to call BCrypt.HashPassword()
directly. I chose the first approach to keep all of my using statements together at the top of the file.
using BC = BCrypt.Net.BCrypt;
using System.Linq;
using WebApi.Entities;
using WebApi.Helpers;
using WebApi.Models.Accounts;
namespace WebApi.Services
{
public interface IAccountService
{
void Register(RegisterRequest model);
bool Authenticate(AuthenticateRequest model);
}
public class AccountService : IAccountService
{
private readonly DataContext _context;
public AccountService(DataContext context)
{
_context = context;
}
public void Register(RegisterRequest model)
{
// create new account object from model
var account = new Account(model);
// hash password
account.PasswordHash = BC.HashPassword(model.Password);
// save account
_context.Accounts.Add(account);
_context.SaveChanges();
}
public bool Authenticate(AuthenticateRequest model)
{
// get account from database
var account = _context.Accounts.SingleOrDefault(x => x.Email == model.Email);
// check account found and verify password
if (account == null || !BC.Verify(model.Password, account.PasswordHash))
{
// authentication failed
return false;
}
else
{
// authentication successful
return true;
}
}
}
}
Need Some ASP.NET Core Help?
Search fiverr for freelance ASP.NET Core developers.
Follow me for updates
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!