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?
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.
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.
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.
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.
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!"); }
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With