Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h1>EDIT: Do not use the Membership Provider as-is because it is horridly inadequate in terms of protecting user's passwords</h1> <p>In light of the fact that <a href="https://www.google.com/?q=membership+provider+hashing+algorithm" rel="nofollow noreferrer">googling "membership provider hashing algorithm"</a> turns up this answer as the first result, and the gospel that will be inferred, it behoves me to warn folks about using the Membership Provider like this and using hashes like SHA-1, MD5 etc to obfuscate passwords in databases.</p> <h2>tl;dr</h2> <p><strong><a href="https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet" rel="nofollow noreferrer">Use a key-derivation function like bcrypt, scrypt or (if you need FIPS compliance) PBKDF2</a> with a work factor sufficient to necessitate the hashing time for a single password to be as close to 1000ms or more.</strong></p> <p>Hashes are easy to brute force these days with ample examples of data breaches in recent history. To prevent your user's passwords from ending up on pastebin in the next hack, ensure that passwords are hashed with a function that takes a <em>sufficiently long time to compute!</em></p> <p>Instead of Membership Provider, try <a href="http://brockallen.com/2014/02/11/introducing-identityreboot/" rel="nofollow noreferrer">IdentityReboot</a> or the <a href="http://www.troyhunt.com/2012/07/stronger-password-hashing-in-net-with.html" rel="nofollow noreferrer">newer implementations from Microsoft that Troy Hunt talks about</a> at the least.</p> <p>It's also interesting that on the same google results mentioned above I find a <a href="https://www.securusglobal.com/community/2014/02/25/cracking-net-membership-password-hashes/" rel="nofollow noreferrer">tutorial showing folks preciously how easy it is</a> to brute force these password hashes using popular tools like JtR or Hashcat. On a custom GPU rig, SHA1 can be cracked at a <a href="https://gist.github.com/epixoip/63c2ad11baf7bbd57544" rel="nofollow noreferrer">staggering rate of 48867 <em>million hashes per second</em>!</a> With a free dictionary like <a href="https://wiki.skullsecurity.org/Passwords" rel="nofollow noreferrer">rockyou or the like</a>, a motivated person with your database will very quickly have most of your users passwords. As a developer, it's your ethical responsibility to do what is necessary to protect the security of your users' passwords.</p> <hr> <p>The default hashing is SHA1 but they also salt it and base64 it:</p> <pre><code>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); } </code></pre> <p>If you want to know more about how to change it I still need to find out (unless using custom provider see below) however SHA-1 is pretty good for now. If you are looking to reverse it or lookup from this these guys did some work on that: <a href="http://forums.asp.net/p/1336657/2899172.aspx" rel="nofollow noreferrer">http://forums.asp.net/p/1336657/2899172.aspx</a></p> <p>This SO question will help in reversing or duplicating this technique if that is what might be needed. <a href="https://stackoverflow.com/questions/530426/reimplement-asp-net-membership-and-user-password-hashing-in-ruby">Reimplement ASP.NET Membership and User Password Hashing in Ruby</a></p> <p>If you are making a custom provider you can create your hashing and encryption algorithms and methods.</p> <pre><code>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)) &gt; 0) { msPasswordDec.Write(Buffer, 0, BytesRead); } cryptoStream.Close(); RetVal = ue.GetString(msPasswordDec.ToArray()); msPasswordDec.Close(); break; } return RetVal; } </code></pre> <p><a href="http://msdn.microsoft.com/en-us/library/aa479048.aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/aa479048.aspx</a></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload