Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 757 Vote(s) - 3.49 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Hash and salt passwords in C#

#1
I was just going through one of DavidHayden's articles on [Hashing User Passwords][1].

Really I can't get what he is trying to achieve.

Here is his code:

private static string CreateSalt(int size)
{
//Generate a cryptographic random number.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buff = new byte[size];
rng.GetBytes(buff);

// Return a Base64 string representation of the random number.
return Convert.ToBase64String(buff);
}

private static string CreatePasswordHash(string pwd, string salt)
{
string saltAndPwd = String.Concat(pwd, salt);
string hashedPwd =
FormsAuthentication.HashPasswordForStoringInConfigFile(
saltAndPwd, "sha1");
return hashedPwd;
}


Is there any other C# method for hashing passwords and adding salt to it?

[1]:

[To see links please register here]


Reply

#2
Salt is used to add an extra level of complexity to the hash, to make it harder to brute-force crack.

From an [article on Sitepoint][1]:

> A hacker can still perform
> what's called a dictionary attack.
> Malicious parties may make a
> dictionary attack by taking, for
> instance, 100,000 passwords that they
> know people use frequently (e.g. city
> names, sports teams, etc.), hash them,
> and then compare each entry in the
> dictionary against each row in the
> database table. If the hackers find a
> match, bingo! They have your password.
> To solve this problem, however, we
> need only salt the hash.
>
> To salt a hash, we simply come up with
> a random-looking string of text,
> concatenate it with the password
> supplied by the user, then hash both
> the randomly generated string and
> password together as one value. We
> then save both the hash and the salt
> as separate fields within the Users
> table.
>
> In this scenario, not only would a
> hacker need to guess the password,
> they'd have to guess the salt as well.
> Adding salt to the clear text improves
> security: now, if a hacker tries a
> dictionary attack, he must hash his
> 100,000 entries with the salt of every
> user row. Although it's still
> possible, the chances of hacking
> success diminish radically.

There is no method automatically doing this in .NET, so you'll have go with the solution above.


[1]:

[To see links please register here]

Reply

#3
What blowdart said, but with a little less code. Use Linq or `CopyTo` to concatenate arrays.

public static byte[] Hash(string value, byte[] salt)
{
return Hash(Encoding.UTF8.GetBytes(value), salt);
}

public static byte[] Hash(byte[] value, byte[] salt)
{
byte[] saltedValue = value.Concat(salt).ToArray();
// Alternatively use CopyTo.
//var saltedValue = new byte[value.Length + salt.Length];
//value.CopyTo(saltedValue, 0);
//salt.CopyTo(saltedValue, value.Length);

return new SHA256Managed().ComputeHash(saltedValue);
}

Linq has an easy way to compare your byte arrays too.

public bool ConfirmPassword(string password)
{
byte[] passwordHash = Hash(password, _passwordSalt);

return _passwordHash.SequenceEqual(passwordHash);
}

Before implementing any of this however, check out [this post](

[To see links please register here]

). For password hashing you may want a slow hash algorithm, not a fast one.

To that end there is the [`Rfc2898DeriveBytes`](

[To see links please register here]

) class which is slow (and can be made slower), and may answer the second part of the original question in that it can take a password and salt and return a hash. See [this question](

[To see links please register here]

) for more information. Note, [Stack Exchange is using `Rfc2898DeriveBytes`](

[To see links please register here]

) for password hashing (source code [here](

[To see links please register here]

)).
Reply

#4
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][1], (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.


[1]:

[To see links please register here]

Reply

#5
Bah, this is better!

[To see links please register here]

and it is better because ..... it performs **Key Stretching** AND uses **HMACSHA512** :)
Reply

#6
create proc [dbo].[hash_pass] @family nvarchar(50), @username nvarchar(50), @pass nvarchar(Max),``` @semat nvarchar(50), @tell nvarchar(50)

as insert into tbl_karbar values (@family,@username,(select HASHBYTES('SHA1' ,@pass)),@semat,@tell)
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through