C# Hashing algorithm class | Asp.Net | .Net Core
In this article, we’ll learn how to secure your password using already implemented C# hashing algorithm class and the importance of password hashing.
Users data is the most important thing in any application so it’s a developer responsibility to keep users data in the most secure way using best practices. When we talk about user account security, first thing comes in our mind is account password.
In any application, when a user creates his account the must have to enter a password. Account password with other account credentials always save in the database so if someone gains unauthorized access to the database then he can also see passwords for all accounts of that system.
Password Hashing
Password Hashing performs a one-way transformation on password, changing the password into another String, called the hashed password. “One-way” means that it is not possible to turn the hashed password back into the original password using the sample algorithm in reverse order.
For Password Hashing, there are several built-in algorithms in all languages(C# also provides e.g. MD5) but for a more secure password, hashing algorithm must be a combination of some built-in algorithms.
I’m going to share a password hashing class for Asp.Net Code. Using this class you can easily Hash a password in a secure string before saving it into a database and also match password with hashed string with a function.
So here’s the Code
using System; using System.Security.Cryptography; namespace MyProject.Helpers { public sealed class SecurePasswordHasherHelper { /// <summary> /// Size of salt /// </summary> private const int SaltSize = 16; /// <summary> /// Size of hash /// </summary> private const int HashSize = 20; /// <summary> /// Creates a hash from a password /// </summary> /// <param name="password">the password</param> /// <param name="iterations">number of iterations</param> /// <returns>the hash</returns> public static string Hash(string password, int iterations) { //create salt byte[] salt; new RNGCryptoServiceProvider().GetBytes(salt = new byte[SaltSize]); //create hash var pbkdf2 = new Rfc2898DeriveBytes(password, salt, iterations); var hash = pbkdf2.GetBytes(HashSize); //combine salt and hash var hashBytes = new byte[SaltSize + HashSize]; Array.Copy(salt, 0, hashBytes, 0, SaltSize); Array.Copy(hash, 0, hashBytes, SaltSize, HashSize); //convert to base64 var base64Hash = Convert.ToBase64String(hashBytes); //format hash with extra information return string.Format("$MYHASH$V1${0}${1}", iterations, base64Hash); } /// <summary> /// Creates a hash from a password with 10000 iterations /// </summary> /// <param name="password">the password</param> /// <returns>the hash</returns> public static string Hash(string password) { return Hash(password, 10000); } /// <summary> /// Check if hash is supported /// </summary> /// <param name="hashString">the hash</param> /// <returns>is supported?</returns> public static bool IsHashSupported(string hashString) { return hashString.Contains("$MYHASH$V1$"); } /// <summary> /// verify a password against a hash /// </summary> /// <param name="password">the password</param> /// <param name="hashedPassword">the hash</param> /// <returns>could be verified?</returns> public static bool Verify(string password, string hashedPassword) { //check hash if (!IsHashSupported(hashedPassword)) { throw new NotSupportedException("The hashtype is not supported"); } //extract iteration and Base64 string var splittedHashString = hashedPassword.Replace("$MYHASH$V1$", "").Split('$'); var iterations = int.Parse(splittedHashString[0]); var base64Hash = splittedHashString[1]; //get hashbytes var hashBytes = Convert.FromBase64String(base64Hash); //get salt var salt = new byte[SaltSize]; Array.Copy(hashBytes, 0, salt, 0, SaltSize); //create hash with given salt var pbkdf2 = new Rfc2898DeriveBytes(password, salt, iterations); byte[] hash = pbkdf2.GetBytes(HashSize); //get result for (var i = 0; i < HashSize; i++) { if (hashBytes[i + SaltSize] != hash[i]) { return false; } } return true; } } }
Add this class to your project and use it like this:
string hashed_password = SecurePasswordHasherHelper.Hash("12345");
12345 equivalent hashed string is $MYHASH$V1$10000$PMCjQg77vX6piW11bo8XKwM2dKjwMk8qOWVj25sMEonKoN2e
Every time when you’ll hash 12345, you’ll get a different string
You can Validate password in this way
if (SecurePasswordHasher.Verify("12345",hashed_password)) { return "Password is Valid"; }
DB Load Hash password How to Match User Enter Password ????
I mean that , when i make my register with clear string password like “MyPassword123” i send in db and hashing password and look like this “MYHASHPASS54dc4sd54cssd4sfcc s4s4sd1s 2sx54dscs5sd” , when i go to login , i use “MyPassword123” ….
To verify your password, you need to give the password instead of
12345
& hashed password(from DB) at the place ofhashed_password
in the below Code.SecurePasswordHasher.Verify("12345",hashed_password)
Hi , i was use your code source for hashing password , but when i try to login , can not do this operations, how to load the password from db ?
You must load Hashed password from DB.