Programing

ASP.NET 멤버십이 사용하는 기본 해시 알고리즘은 무엇입니까?

crosscheck 2021. 1. 10. 19:14

ASP.NET 멤버십이 사용하는 기본 해시 알고리즘은 무엇입니까?


ASP.NET 멤버십이 사용하는 기본 해시 알고리즘은 무엇입니까? 그리고 어떻게 바꿀 수 있습니까?


편집 : 사용자의 암호를 보호하는 측면에서 끔찍하게 부적절하므로 Membership Provider를있는 그대로 사용하지 마십시오.

인터넷 검색 "멤버쉽 공급자 해싱 알고리즘" 이이 답변을 첫 번째 결과로 나타냈다 는 사실 과 추론 될 복음에 비추어 볼 때 회원 공급자를 이와 같이 사용하고 SHA-1과 같은 해시를 사용하는 것에 대해 사람들에게 경고하는 것이 좋습니다. , MD5 등을 사용하여 데이터베이스에서 암호를 난독 화합니다.

tl; dr

bcrypt, scrypt 또는 (FIPS 준수가 필요한 경우) PBKDF2같은 키 파생 기능 을 사용하여 단일 암호가 1000ms 이상에 가까워 지도록 해싱 시간을 필요로 할 수 있습니다.

해시는 최근 역사상 데이터 유출 사례가 많기 때문에 무차별 대입하기 쉽습니다. 사용자의 암호가 다음 해킹에서 pastebin으로 끝나는 것을 방지하려면 계산 하는 데 충분히 오래 걸리는 함수로 암호를 해시해야합니다 !

Membership Provider 대신 Troy Hunt 가 최소한 언급 한 MicrosoftIdentityReboot 또는 최신 구현을 사용해보십시오 .

또한 위에서 언급 한 동일한 Google 결과에서 JtR 또는 Hashcat과 같은 인기있는 도구를 사용하여 이러한 암호 해시를 무차별 대입 하는 것이 얼마나 쉬운 지 보여주는 자습서를 찾은 것도 흥미 롭습니다. 커스텀 GPU 장비에서 SHA1은 초당 48867 백만 해시놀라운 속도 로 크랙 될 수 있습니다 ! rockyou 등과 같은 무료 사전을 사용하면 데이터베이스를 사용하는 동기 부여 된 사람이 대부분의 사용자 암호를 매우 빠르게 갖게됩니다. 개발자로서 사용자 암호의 보안을 보호하는 데 필요한 작업을 수행하는 것은 윤리적 책임입니다.


기본 해싱은 SHA1이지만 솔트 및 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);
}

변경 방법에 대해 더 알고 싶다면 여전히 (사용자 지정 공급자를 사용하지 않는 한 아래 참조) 알아 내야하지만 SHA-1은 현재 꽤 좋습니다. 당신이 그것을 역전 시키거나 이것에서 조회를 찾고 있다면이 사람들은 그것에 대해 약간의 작업을했습니다 : http://forums.asp.net/p/1336657/2899172.aspx

이 SO 질문은 필요한 경우이 기술을 뒤집거나 복제하는 데 도움이 될 것입니다. Ruby에서 ASP.NET 멤버십 및 사용자 암호 해싱 다시 구현

사용자 지정 공급자를 만드는 경우 해싱 및 암호화 알고리즘과 방법을 만들 수 있습니다.

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


Ryan Christensen위 답변 은 완전하지 않습니다. 솔트를 byte []로 변환하는 부분이 올바르지 않습니다.

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

public string Hash(string value, string salt)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(value);
        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);
    }

The default hash algorithm type is SHA1. There are two ways that you can change this.

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

Machine Key configuration page from IIS 7 administration tool

2) If you are working with IIS 6 you can change the hash algorithm type 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 hashing algorithm types. A bit of 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 these classes inherit from HashAlgorithm.

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


The default hash algorithm changed to HMACSHA256 in the .NET 4.0 Framework.

Note that unlike SHA-1, HMAC SHA-256 is a keyed hash. If your hashes are behaving non-deterministically, you probably haven't set a key, forcing it to use a random one. Something similar to the following would be the culprit (which is what I just spent an hour figuring out :p ).

HashAlgorithm.Create(Membership.HashAlgorithmType)

If you wish to have it work with an existing provider you can revert it back to the former defaults using this guide.


There is one correction in hashing algorithm, you must use:

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

instead of

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

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


I attach a snippet showing the code as in Rawbert's answer 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 working code from an active application

ReferenceURL : https://stackoverflow.com/questions/1137368/what-is-default-hash-algorithm-that-asp-net-membership-uses