What is the default hash algorithm that uses ASP.NET membership?

What is the default hash algorithm that uses ASP.NET membership? And how can I change it?

+51
authentication hash membership
Jul 16 '09 at 12:51
source share
6 answers

EDIT: do not use member membership as is because it is terribly inadequate in terms of protecting user passwords

In light of the fact that googling is a “membership provider hash algorithm” , this answer is the first, and the gospel to be deduced should warn people about using a membership provider like this and use hashes like SHA-1, MD5 and etc. to confuse passwords in databases.

TL; DR

Use a key generation function such as bcrypt, scrypt or (if you need FIPS compliance) PBKDF2 with a sufficient working coefficient so that the hash time for one password is as close as possible to 1000 ms or more.

Hashes these days are easy to overdo with plentiful examples of data breaches in recent history. To ensure that your user passwords do not get into pastabin in the next hack, make sure that passwords are hashed with a function that takes a long time to calculate!

Instead of a membership provider, try IdentityReboot or newer versions from Microsoft, which Troy Hunt talks about at least.

It’s also interesting that for the same google results mentioned above, I find a tutorial in which people really appreciate how easy it is to go over these passwords hashes using popular tools like JtR or Hashcat. On a user platform, SHA1 GPU can be hacked at a staggering 48867 million hashes per second! With a free dictionary, like rockyou or the like , a motivated person with your database will very quickly have most of your user passwords. As a developer, your ethical responsibility is to do what is necessary to protect the passwords of your users.




The default hash is SHA1, but they will also merge it and base64:

public string EncodePassword(string pass, string salt) { byte[] bytes = Encoding.Unicode.GetBytes(pass); byte[] src = Encoding.Unicode.GetBytes(salt); byte[] dst = new byte[src.Length + bytes.Length]; Buffer.BlockCopy(src, 0, dst, 0, src.Length); Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); byte[] inArray = algorithm.ComputeHash(dst); return Convert.ToBase64String(inArray); } 

If you want to know more about how to change it, I still need to find out (if you do not use a user provider, see below), however SHA-1 is pretty good right now. If you want to cancel it or look at it, these guys have worked a bit on this: http://forums.asp.net/p/1336657/2899172.aspx

This SO question will help in reverse or duplication of this method, if that is what you might need. Override ASP.NET Membership and User Password in Ruby

If you are creating a custom provider, you can create your own hashing and encryption algorithms and methods.

 private byte[] ConvertPasswordForStorage(string Password) { System.Text.UnicodeEncoding ue = new System.Text.UnicodeEncoding(); byte[] uePassword = ue.GetBytes(Password); byte[] RetVal = null; switch (_PasswordFormat) { case MembershipPasswordFormat.Clear: RetVal = uePassword; break; case MembershipPasswordFormat.Hashed: HMACSHA1 SHA1KeyedHasher = new HMACSHA1(); SHA1KeyedHasher.Key = _ValidationKey; RetVal = SHA1KeyedHasher.ComputeHash(uePassword); break; case MembershipPasswordFormat.Encrypted: TripleDESCryptoServiceProvider tripleDes = new TripleDESCryptoServiceProvider(); tripleDes.Key = _DecryptionKey; tripleDes.IV = new byte[8]; MemoryStream mStreamEnc = new MemoryStream(); CryptoStream cryptoStream = new CryptoStream(mStreamEnc, tripleDes.CreateEncryptor(), CryptoStreamMode.Write); cryptoStream.Write(uePassword, 0, uePassword.Length); cryptoStream.FlushFinalBlock(); RetVal = mStreamEnc.ToArray(); cryptoStream.Close(); break; } return RetVal; } private string GetHumanReadablePassword(byte[] StoredPassword) { System.Text.UnicodeEncoding ue = new System.Text.UnicodeEncoding(); string RetVal = null; switch (_PasswordFormat) { case MembershipPasswordFormat.Clear: RetVal = ue.GetString(StoredPassword); break; case MembershipPasswordFormat.Hashed: throw new ApplicationException( "Password cannot be recovered from a hashed format"); case MembershipPasswordFormat.Encrypted: TripleDESCryptoServiceProvider tripleDes = new TripleDESCryptoServiceProvider(); tripleDes.Key = _DecryptionKey; tripleDes.IV = new byte[8]; CryptoStream cryptoStream = new CryptoStream(new MemoryStream(StoredPassword), tripleDes.CreateDecryptor(), CryptoStreamMode.Read); MemoryStream msPasswordDec = new MemoryStream(); int BytesRead = 0; byte[] Buffer = new byte[32]; while ((BytesRead = cryptoStream.Read(Buffer, 0, 32)) > 0) { msPasswordDec.Write(Buffer, 0, BytesRead); } cryptoStream.Close(); RetVal = ue.GetString(msPasswordDec.ToArray()); msPasswordDec.Close(); break; } return RetVal; } 

http://msdn.microsoft.com/en-us/library/aa479048.aspx

+45
Jul 16 '09 at 12:58
source share

The default hash algorithm type is SHA1. There are two ways to change this.

1) If you are working with IIS 7, you can update it using the "Machine Key" configuration (shown below). This allows you to select an encryption method from the list of available parameters and specify keys or key generation options.

Machine Key configuration page from IIS 7 administration tool

2) If you are working with IIS 6, you can change the type of hash algorithm using the membership element in the web.config file:

 <membership defaultProvider="provider name" userIsOnlineTimeWindow="number of minutes" hashAlgorithmType="SHA1"> <providers>...</providers> </membership> 

According to the documentation, the string value of the hashAlgorithmType attribute can be any of the provided .Net hash algorithm types. A little digging shows that the valid values ​​for ASP.Net 2, 3, and 3.5 are: MD5 , RIPEMD160 , SHA1 , SHA256 , SHA384 , SHA512 . The important part here is that all of these classes inherit from HashAlgorithm .

The value of the hashAlgorithmType attribute can also be an entry from cryptoNameMapping in the machine.config file. You can use this if you need a third-party hashing algorithm. The machine.config file can usually be found in C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG if you are using ASP.Net 2 or later. You can learn more about setting these values here .

+26
Jul 16 '09 at 13:07
source share

The default hash algorithm has been changed to HMACSHA256 in the .NET 4.0 platform.

Note that unlike SHA-1, HMAC SHA-256 is a hash key. If your hashes are non-deterministic, you probably did not specify a key, forcing it to use a random one. Something like the following would be the culprit (this is what I just spent an hour finding out: p).

 HashAlgorithm.Create(Membership.HashAlgorithmType) 

If you want it to work with an existing provider, you can revert it back to the previous default values ​​using this guide .

+26
Nov 19 '10 at 17:24
source share

Ryan Christensen's answer above is not complete. The part in which it converts salt to byte [] is incorrect.

This is a working example that I implemented in a solution for a client:

 public string EncodePassword(string pass, string salt) { byte[] bytes = Encoding.Unicode.GetBytes(pass); byte[] src = Convert.FromBase64String(salt); byte[] dst = new byte[src.Length + bytes.Length]; Buffer.BlockCopy(src, 0, dst, 0, src.Length); Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); byte[] inArray = algorithm.ComputeHash(dst); return Convert.ToBase64String(inArray); } 
+25
Jan 27 2018-12-12T00:
source share

There is one correction in the hashing algorithm, you should use:

 byte[] src = Convert.FromBase64String(salt); 

instead

 byte[] src = Encoding.Unicode.GetBytes(salt); 

Read the article http://svakodnevnica.com.ba/index.php?option=com_kunena&func=view&catid=4&id=4&Itemid=5&lang=en#6

+2
Aug 04 2018-11-12T00:
source share

I am attaching a snippet showing the code as in Rawbert, answering above in F #

 open System open System.Security.Cryptography open System.Text module PasswordHelper = let EncodePassword(pass : string, salt : string) = let bytes = Encoding.Unicode.GetBytes(pass) let src = Convert.FromBase64String(salt) let dst : byte array = Array.zeroCreate (src.Length + bytes.Length) Buffer.BlockCopy(src, 0, dst, 0, src.Length) Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length) let algorithm = HashAlgorithm.Create("SHA1") let inArray = algorithm.ComputeHash(dst) Convert.ToBase64String(inArray) 

This is the working code from the active application.

0
Nov 18 '14 at 9:19
source share



All Articles