Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hashing passwords with MD5 or sha-256 C#

Tags:

c#

hash

sha256

I'm writing a register form for a application but still having problems with being new to c#.

I am looking to encrypt/hash passwords to md5 or sha-256, preferably sha-256.

Any good examples? I want it to be able to take the information from "string password;" and then hash it and store in the variable "string hPassword;". Any ideas?

like image 621
Sean Avatar asked Dec 01 '10 22:12

Sean


People also ask

Should I use MD5 or SHA-256?

The SHA-256 algorithm returns hash value of 256-bits, or 64 hexadecimal digits. While not quite perfect, current research indicates it is considerably more secure than either MD5 or SHA-1. Performance-wise, a SHA-256 hash is about 20-30% slower to calculate than either MD5 or SHA-1 hashes.

Should I use SHA-256 for passwords?

Google recommends using stronger hashing algorithms such as SHA-256 and SHA-3. Other options commonly used in practice are bcrypt , scrypt , among many others that you can find in this list of cryptographic algorithms.

Is MD5 good for password hashing?

Unfortunately, MD5 has been cryptographically broken and considered insecure. For this reason, it should not be used for anything. Instead, developers should switch to the Secure Hash Algorithm or a Symmetric Cryptographic Algorithm.

Which algorithm is best for hashing passwords?

To protect passwords, experts suggest using a strong and slow hashing algorithm like Argon2 or Bcrypt, combined with salt (or even better, with salt and pepper). (Basically, avoid faster algorithms for this usage.) To verify file signatures and certificates, SHA-256 is among your best hashing algorithm choices.


2 Answers

Don't use a simple hash, or even a salted hash. Use some sort of key-strengthening technique like bcrypt (with a .NET implementation here) or PBKDF2 (with a built-in implementation).

Here's an example using PBKDF2.

To generate a key from your password...

string password = GetPasswordFromUserInput();  // specify that we want to randomly generate a 20-byte salt using (var deriveBytes = new Rfc2898DeriveBytes(password, 20)) {     byte[] salt = deriveBytes.Salt;     byte[] key = deriveBytes.GetBytes(20);  // derive a 20-byte key      // save salt and key to database } 

And then to test if a password is valid...

string password = GetPasswordFromUserInput();  byte[] salt, key; // load salt and key from database  using (var deriveBytes = new Rfc2898DeriveBytes(password, salt)) {     byte[] newKey = deriveBytes.GetBytes(20);  // derive a 20-byte key      if (!newKey.SequenceEqual(key))         throw new InvalidOperationException("Password is invalid!"); } 
like image 197
LukeH Avatar answered Sep 20 '22 02:09

LukeH


You're going to want to use the System.Security.Cryptography namespace; specifically, the MD5 class or the SHA256 class.

Drawing a bit from the code on this page, and with the knowledge that both classes have the same base class (HashAlgorithm), you could use a function like this:

public string ComputeHash(string input, HashAlgorithm algorithm) {    Byte[] inputBytes = Encoding.UTF8.GetBytes(input);     Byte[] hashedBytes = algorithm.ComputeHash(inputBytes);     return BitConverter.ToString(hashedBytes); } 

Then you could call it like this (for MD5):

string hPassword = ComputeHash(password, new MD5CryptoServiceProvider()); 

Or for SHA256:

string hPassword = ComputeHash(password, new SHA256CryptoServiceProvider()); 

Edit: Adding Salt Support
As dtb pointed out in the comments, this code would be stronger if it included the ability to add salt. If you're not familiar with it, salt is a set of random bits that are included as an input to the hashing function, which goes a long way to thwart dictionary attacks against a hashed password (e.g., using a rainbow table). Here's a modified version of the ComputeHash function that supports salt:

public static string ComputeHash(string input, HashAlgorithm algorithm, Byte[] salt) {    Byte[] inputBytes = Encoding.UTF8.GetBytes(input);     // Combine salt and input bytes    Byte[] saltedInput = new Byte[salt.Length + inputBytes.Length];    salt.CopyTo(saltedInput, 0);    inputBytes.CopyTo(saltedInput, salt.Length);     Byte[] hashedBytes = algorithm.ComputeHash(saltedInput);     return BitConverter.ToString(hashedBytes); } 

Hope this has been helpful!

like image 42
Donut Avatar answered Sep 17 '22 02:09

Donut