Что такое алгоритм хеширования по умолчанию, который использует членство ASP.NET? - PullRequest
53 голосов
/ 16 июля 2009

Что такое алгоритм хеширования по умолчанию, который использует членство в ASP.NET? И как я могу это изменить?

Ответы [ 6 ]

46 голосов
/ 16 июля 2009

РЕДАКТИРОВАТЬ: не используйте поставщика членства как есть, потому что он ужасно неадекватен с точки зрения защиты паролей пользователей

В свете того факта, что прибегая к помощи "алгоритма хэширования провайдера членства" включает этот ответ в качестве первого результата, и евангелие, которое будет выведено, я должен предупредить людей об использовании провайдера членства как это и использование хэшей, таких как SHA-1, MD5 и т. д., чтобы скрыть пароли в базах данных.

ТЛ; др

Используйте функцию получения ключа, такую ​​как bcrypt, scrypt или (если вам требуется соответствие FIPS) PBKDF2 с рабочим фактором, достаточным для того, чтобы время хеширования для одного пароля было как можно ближе к 1000 мс или более.

В наши дни хэши легко перебрать с помощью многочисленных примеров взлома данных в недавней истории. Чтобы пароли вашего пользователя не попали на pastebin при следующем взломе, убедитесь, что пароли хешируются с помощью функции, которая занимает достаточно много времени для вычисления!

Вместо поставщика членства, попробуйте IdentityReboot или более новые реализации от Microsoft, о которых Трой Хант говорит как минимум о .

Также интересно, что на тех же самых результатах Google, упомянутых выше, я нахожу учебник , показывающий людям, как просто легко перебирать эти хеши паролей с помощью популярных инструментов, таких как JtR или Hashcat. На пользовательском графическом процессоре SHA1 может быть взломан с потрясающей скоростью 48867 миллионов хешей в секунду ! С помощью бесплатного словаря, например rockyou или подобного , a мотивированный человек с вашей базой данных очень быстро будет иметь большинство паролей ваших пользователей. Как разработчик, вы несете ответственность за то, чтобы сделать все необходимое для защиты паролей ваших пользователей.


Хеширование по умолчанию - 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 поможет изменить или дублировать эту технику, если это то, что может понадобиться. Переопределение членства в ASP.NET и хеширования пароля пользователя в Ruby

Если вы делаете собственного провайдера, вы можете создавать свои алгоритмы и методы хеширования и шифрования.

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

31 голосов
/ 27 января 2012

Ответ выше Райана Кристенсена не завершен. Часть, где она преобразует соль в байт [], неверна.

Это рабочий пример, который я реализовал в решении для клиента:

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);
    }
27 голосов
/ 16 июля 2009

Тип алгоритма хеширования по умолчанию - SHA1. Это можно изменить двумя способами.

1) Если вы работаете с IIS 7, вы можете обновить его, используя конфигурацию «Ключ компьютера» (см. Ниже). Это позволяет выбрать метод шифрования из списка доступных параметров и указать ключи или параметры генерации ключа.

Machine Key configuration page from IIS 7 administration tool

2) Если вы работаете с IIS 6, вы можете изменить тип алгоритма хеширования, используя элемент членства в файле web.config:

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

Согласно документации, строковое значение атрибута hashAlgorithmType может быть любым из предоставленных типов алгоритма хеширования .Net. Немного копания показывает, что действительными значениями для ASP.Net 2, 3 и 3.5 являются MD5, RIPEMD160, SHA1, SHA256, SHA384, SHA512. Важной частью здесь является то, что все эти классы наследуются от HashAlgorithm.

Значением атрибута hashAlgorithmType также может быть запись из элемента cryptoNameMapping в файле machine.config. Вы можете использовать это, если вам требуется сторонний алгоритм хеширования. Файл machine.config обычно находится в C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG, если вы используете ASP.Net 2 или новее. Вы можете прочитать больше о настройке этих значений здесь .

26 голосов
/ 19 ноября 2010

Алгоритм хеширования по умолчанию изменен на HMACSHA256 в .NET 4.0 Framework.

Обратите внимание, что в отличие от SHA-1, HMAC SHA-256 является хеш-кодом с ключами. Если ваши хеши ведут себя недетерминированно, вы, вероятно, не установили ключ, заставляя его использовать случайный ключ. Нечто похожее на следующее было бы виновником (вот что я потратил на то, чтобы выяснить час: p).

HashAlgorithm.Create(Membership.HashAlgorithmType)

Если вы хотите, чтобы он работал с существующим провайдером, вы можете вернуть его к прежним настройкам по умолчанию, используя это руководство .

2 голосов
/ 04 августа 2011

В алгоритме хеширования есть одна поправка, которую вы должны использовать:

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

вместо

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

Читать статью http://svakodnevnica.com.ba/index.php?option=com_kunena&func=view&catid=4&id=4&Itemid=5&lang=en#6

0 голосов
/ 18 ноября 2014

Я прикрепляю фрагмент кода, как показано в ответе Равберта выше, в 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)

Это рабочий код из активного приложения

...