2010-07-06 2 views
12

У меня возникла интересная проблема .. Кажется, что ComputeHash() для хэша «HMACSHA256» не ведет себя детерминистически .. если я создаю два экземпляра HashAlgorithm с помощью HashAlgorithm.Create («HMACSHA256») .. И запустите ComputeHash, я получаю два разных результата. Ниже приведен пример статического класса, демонстрирующего это поведение.Почему ComputeHash не действует детерминистически?

internal static string HashPassword(byte[] bAll) 
{ 
    using (HashAlgorithm s = HashAlgorithm.Create("HMACSHA256")) 
    { 
     return Convert.ToBase64String(s.ComputeHash(bAll)); 
    } 
} 

Я также попытался сделать вызов ноны статическим (на самом деле он начал не статичен, и у меня есть двойной и тройной и quadrudruple проверил мой входной массив .. его абсолютно одинаково на каждый вызов .. я ве даже сделал материал в Immidiate окно, как:

Convert.ToBase64String(HashAlgorithm.Create("HMACSHA256").ComputeHash(bAll) 

И работает, что дважды в окне immidiates через точку останова в методе возвращает два разных хэши ..

Я знаю, Hash, предполагают, чтобы быть детерминированным. Итак, что дает? Что-то происходит с запуском в отладчике? Или любые другие идеи? на самом деле это просто две странные слова прямо сейчас :-P ..

Благодаря Джош

+3

Есть ли у вас короткие данные об образцах, которые проявляют эту проблему? Что-нибудь меняет «bAll» между или во время звонков? –

+4

HMAC - это хеш-ключ.Я не вижу ключа в вашем примере кода. Я считаю, что ключ задан случайным образом, если вы не укажете его явно. – dtb

+0

ничего не меняется между вызовами. Как я уже сказал, я даже сделал это из окна immidiates. Вот 4 звонка из окна Immidiates .. да, они не идеальны, потому что вы должны распоряжаться HashAlgorithm, но результаты - это то же самое через окно Immidiates или метод. (Я включу их в следующий комментарий, потому что у меня нет места для копирования их здесь) –

ответ

24

HMAC является ключом хэш. Я не вижу ключа в вашем примере кода.

HashAlgorithm.Create("HMACSHA256") создает экземпляр HashAlgorithm, поэтому он ничего не знает о ключе. Это, вероятно, просто вызывает this HMACSHA256 Constructor:

public HMACSHA256()

Инициализирует новый экземпляр класса HMACSHA256 с случайным ключом.

Вы хотите this constructor:

public HMACSHA256(byte[] key)

Инициализирует новый экземпляр класса HMACSHA256 с заданными ключевыми данными.

Если вы не хотите, чтобы жестко прописать алгоритм HMAC, вы можете использовать KeyedHashAlgorithm.Create и поставить конкретный ключ, установив KeyedHashAlgorithm.Key свойства.

Если вы не хотите использовать ключ, используйте несимметричный хеш, такой как SHA256.

+0

Лучше всего использовать ['KeyedHashAlgorithm.Create'] (http://msdn.microsoft.com/en-us/library/s5zz2x4d.aspx). Урок: узнайте свои хеши! – Randolpho

+0

Я собираюсь заглянуть в материал провайдера и выяснить, почему MS была/не выполняет ключевой хэш, но использует HashAlgorithm.Create(), когда gen это. Возможно, я использую 2.0-исходный пакет ASP.NET Provider source source с 4.0 framework. В любом случае, спасибо, указав мне в правильном направлении. –

+0

@Josh: Есть несколько мест, где у MS была «удивительная» случайность. Например, некоторые настройки CypherMode для шифрования используют случайный вектор инициализации, если вы не укажете. Самое интересное, когда ваше шифрование и дешифрование отлично работают для всех, кроме первых 8 байтов ваших данных. Я думаю, что они приняли здесь хорошее решение. Я предпочел бы, чтобы программа завершилась неудачно, потому что я не понимаю параметры безопасности, которые вам нужны, чем по умолчанию для «рабочего», но менее безопасного состояния. – Brian

3

Вам нужен ключ для HMACSHA256. Ключ будет случайным, если он не будет передан в конструктор.

5

Просто добавив к этому в надежде спасти кого-то головную боль, через которую я прошел.

В случае .Net Memberhip Provider, убедитесь, что у вас есть настройки в вашем web.config или app.config. Иначе он автоматически генерирует свой собственный ключ ... дерьмо на аутентификации, а затем воинственно смеется над вами в конце.