There are multiple hash algorithms you can choose from in .NET Core. Some do not use any key, some use symmetric keys, and some use asymmetric keys.
There are two important factors to consider when choosing a hash algorithm:
Here are some common hashing algorithms:
Algorithm |
Hash size |
Description |
MD5 |
16 bytes |
This is commonly used because it is fast, but it is not collision-resistant. |
SHA1, SHA256, SHA384, SHA512 |
20 bytes, 32 bytes, 48 bytes, 64 bytes |
These are Secure Hashing Algorithm 2nd generation algorithms (SHA2) with different hash sizes. The use of SHA1s on the Internet has been deprecated since 2011. |
In the Ch11_CryptographyLib
class library project, add a new class named User
. This will represent a user stored in memory, a file, or a database:
namespace Packt.CS7 { public class User { public string Name { get; set; } public string Salt { get; set; } public string SaltedHashedPassword { get; set; } } }
Add the following code to the Protector
class. We will use a dictionary to store multiple users in memory. There are two methods, one to register a new user and one to validate their password when they subsequently log in:
private static Dictionary<string, User> Users = new Dictionary<string, User>(); public static User Register(string username, string password) { // generate a random salt var rng = RandomNumberGenerator.Create(); var saltBytes = new byte[16]; rng.GetBytes(saltBytes); var saltText = Convert.ToBase64String(saltBytes); // generate the salted and hashed password var sha = SHA256.Create(); var saltedPassword = password + saltText; var saltedhashedPassword = Convert.ToBase64String( sha.ComputeHash(Encoding.Unicode.GetBytes(saltedPassword))); var user = new User { Name = username, Salt = saltText, SaltedHashedPassword = saltedhashedPassword }; Users.Add(user.Name, user); return user; } public static bool CheckPassword(string username, string password) { if (!Users.ContainsKey(username)) { return false; } var user = Users[username]; // re-generate the salted and hashed password var sha = SHA256.Create(); var saltedPassword = password + user.Salt; var saltedhashedPassword = Convert.ToBase64String( sha.ComputeHash(Encoding.Unicode.GetBytes(saltedPassword))); return (saltedhashedPassword == user.SaltedHashedPassword); }
Add a new console application project named Ch11_HashingApp
. Add a reference to the Ch11_CryptographyLib
assembly as you did before, and then import the following namespace and type:
using Packt.CS7; using static System.Console;
In the Main
method, add the following statements to register a user and prompt to register a second user, and then prompt to log in as one of those users and validate the password:
WriteLine("A user named Alice has been registered with Pa$$w0rd as her password."); var alice = Protector.Register("Alice", "Pa$$w0rd"); WriteLine($"Name: {alice.Name}"); WriteLine($"Salt: {alice.Salt}"); WriteLine( $"Salted and hashed password: {alice.SaltedHashedPassword}"); WriteLine(); Write("Enter a different username to register: "); string username = ReadLine(); Write("Enter a password to register: "); string password = ReadLine(); var user = Protector.Register(username, password); WriteLine($"Name: {user.Name}"); WriteLine($"Salt: {user.Salt}"); WriteLine( $"Salted and hashed password: {user.SaltedHashedPassword}"); bool correctPassword = false; while (!correctPassword) { Write("Enter a username to log in: "); string loginUsername = ReadLine(); Write("Enter a password to log in: "); string loginPassword = ReadLine(); correctPassword = Protector.CheckPassword( loginUsername, loginPassword); if (correctPassword) { WriteLine( $"Correct! {loginUsername} has been logged in."); } else { WriteLine("Invalid username or password. Try again."); } }
Run the console application and view the output:
A user named Alice has been registered with Pa$$w0rd as her password. Name: Alice Salt: tLn3gRn9DXmp2oeuvBSxTg== Salted and hashed password: w8Ub2aH5NNQ8MJarYsUgm29bbbl0lV/9dlozjWs2Ipk= Enter a different username to register: Bob Enter a password to register: Pa$$w0rd Name: Bob Salt: zPU9YyFLaz0idhQkKpzY+g== Salted and hashed password: 8w14w8WNHoZddEeIx2+UJhpHQqSs4EmyoazqjbmmEz0= Enter a username to log in: Bob Enter a password to log in: secret Invalid username or password. Try again. Enter a username to log in: Alice Enter a password to log in: secret Invalid username or password. Try again. Enter a username to log in: Bob Enter a password to log in: Pa$$w0rd Correct! Bob has been logged in.
3.133.142.2