Md5 Hash with Salt for Keeping Password in Db in C#

MD5 hash with salt for keeping password in DB in C#

You can use the HMACMD5 class:

var hmacMD5 = new HMACMD5(salt);
var saltedHash = hmacMD5.ComputeHash(password);

Works with SHA-1, SHA256, SHA384, SHA512 and RIPEMD160 as well:

var hmacSHA1 = new HMACSHA1(salt);
var saltedHash = hmacSHA1.ComputeHash(password);

Both salt and password are expected as byte arrays.

If you have strings you'll have to convert them to bytes first:

var salt = System.Text.Encoding.UTF8.GetBytes("my salt");
var password = System.Text.Encoding.UTF8.GetBytes("my password");

create md5 hash (salt+value)

Hope this will help, it's some modification from given link

class Program {
static void Main(string[] args) {
var provider = MD5.Create();
string salt = "S0m3R@nd0mSalt";
string password = "SecretPassword";
byte[] bytes = provider.ComputeHash(Encoding.ASCII.GetBytes(salt + password));
string computedHash = BitConverter.ToString(bytes);

Console.WriteLine(computedHash.Replace("-", ""));
}
}

Hash and salt passwords in C#

Actually this is kind of strange, with the string conversions - which the membership provider does to put them into config files. Hashes and salts are binary blobs, you don't need to convert them to strings unless you want to put them into text files.

In my book, Beginning ASP.NET Security, (oh finally, an excuse to pimp the book) I do the following

static byte[] GenerateSaltedHash(byte[] plainText, byte[] salt)
{
HashAlgorithm algorithm = new SHA256Managed();

byte[] plainTextWithSaltBytes =
new byte[plainText.Length + salt.Length];

for (int i = 0; i < plainText.Length; i++)
{
plainTextWithSaltBytes[i] = plainText[i];
}
for (int i = 0; i < salt.Length; i++)
{
plainTextWithSaltBytes[plainText.Length + i] = salt[i];
}

return algorithm.ComputeHash(plainTextWithSaltBytes);
}

The salt generation is as the example in the question. You can convert text to byte arrays using Encoding.UTF8.GetBytes(string). If you must convert a hash to its string representation you can use Convert.ToBase64String and Convert.FromBase64String to convert it back.

You should note that you cannot use the equality operator on byte arrays, it checks references and so you should simply loop through both arrays checking each byte thus

public static bool CompareByteArrays(byte[] array1, byte[] array2)
{
if (array1.Length != array2.Length)
{
return false;
}

for (int i = 0; i < array1.Length; i++)
{
if (array1[i] != array2[i])
{
return false;
}
}

return true;
}

Always use a new salt per password. Salts do not have to be kept secret and can be stored alongside the hash itself.

How to salt and hash a password value using c#?

The most popular way to do this is using a hashing algorithm. There's an excellent blog post here about how to use the MD5 algorithm to hash a string, but there are many other examples in the System.Cryptography namespace.

As for #2, the general step-by-step guide to how this would work would be the following:

On registration:

  1. Hash a user's password using your specified algorithm and store it in the database
  2. Salt this hash (optional, but preferred)

On login / user & password check:

  1. Look up in the database for the username
  2. If it exists, retrieve the hashed password
  3. Hash and salt the entered password and compare it to the retrieved password

It's all relatively long-winded, but it's very secure.

There's another extremely in-depth guide on hashing and salting here.

ASP.NET Hash password using MD5

The output of any hash function is a collection of bytes, not a collection of text. So when you enter text as a test you are probably entering a text conversion of that byte array. Simply converting it in SQL to a binary(16) is not correct, you need to do a proper conversion, which is something you cannot do in SQL. This also explains why changing the datatype of the column doesn't work either.

When hashes are expressed as strings it's usually via hex values of each byte, or via a character set encoder. In order to switch between them you need to figure out which one is in use and perform the conversion in code, not by switching the datatypes in SQL

How to generate an md5 hash with a plaintext string and a known salt

The below given function generates a hash for the given plain text value and returns a base64-encoded result. Before the hash is computed, a random salt is generated and appended to the plain text. This salt is stored at the end of the hash value, so it can be used later for hash verification.


Plaintext value to be hashed. The function does not check whether this parameter is null.


Name of the hash algorithm. Allowed values are: "MD5", "SHA1","SHA256", "SHA384", and "SHA512" (if any other value is specified MD5 hashing algorithm will be used). This value is case-insensitive.

In your case set hashAlgorithm to "MD5"


Salt bytes. This parameter can be null, in which case a random salt value will be generated.


Hash value formatted as a base64-encoded string.

public static string ComputeHash(string   plainText,
string hashAlgorithm,
byte[] saltBytes)
{
// If salt is not specified, generate it on the fly.
if (saltBytes == null)
{
// Define min and max salt sizes.
int minSaltSize = 4;
int maxSaltSize = 8;

// Generate a random number for the size of the salt.
Random random = new Random();
int saltSize = random.Next(minSaltSize, maxSaltSize);

// Allocate a byte array, which will hold the salt.
saltBytes = new byte[saltSize];

// Initialize a random number generator.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

// Fill the salt with cryptographically strong byte values.
rng.GetNonZeroBytes(saltBytes);
}

// Convert plain text into a byte array.
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

// Allocate array, which will hold plain text and salt.
byte[] plainTextWithSaltBytes =
new byte[plainTextBytes.Length + saltBytes.Length];

// Copy plain text bytes into resulting array.
for (int i=0; i < plainTextBytes.Length; i++)
plainTextWithSaltBytes[i] = plainTextBytes[i];

// Append salt bytes to the resulting array.
for (int i=0; i < saltBytes.Length; i++)
plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i];

// Because we support multiple hashing algorithms, we must define
// hash object as a common (abstract) base class. We will specify the
// actual hashing algorithm class later during object creation.
HashAlgorithm hash;

// Make sure hashing algorithm name is specified.
if (hashAlgorithm == null)
hashAlgorithm = "";

// Initialize appropriate hashing algorithm class.
switch (hashAlgorithm.ToUpper())
{
case "SHA1":
hash = new SHA1Managed();
break;

case "SHA256":
hash = new SHA256Managed();
break;

case "SHA384":
hash = new SHA384Managed();
break;

case "SHA512":
hash = new SHA512Managed();
break;

default:
hash = new MD5CryptoServiceProvider();
break;
}

// Compute hash value of our plain text with appended salt.
byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);

// Create array which will hold hash and original salt bytes.
byte[] hashWithSaltBytes = new byte[hashBytes.Length +
saltBytes.Length];

// Copy hash bytes into resulting array.
for (int i=0; i < hashBytes.Length; i++)
hashWithSaltBytes[i] = hashBytes[i];

// Append salt bytes to the result.
for (int i=0; i < saltBytes.Length; i++)
hashWithSaltBytes[hashBytes.Length + i] = saltBytes[i];

// Convert result into a base64-encoded string.
string hashValue = Convert.ToBase64String(hashWithSaltBytes);

// Return the result.
return hashValue;
}

For more details refer here.



Related Topics



Leave a reply



Submit