Какую криптографическую хэш-функцию выбрать?

.NET framework поставляется с 6 различными алгоритмами хэширования:

  • MD5: 16 байт (время до хэша 500 МБ: 1462 МС)
  • SHA1: 20 байт (1644 МС)
  • SHA256: 32 байта (5618 МС)
  • SHA384: 48 байт (3839 МС)
  • SHA512: 64 байта (3820 МС)
  • RIPEMD: 20 байт (7066 МС)

каждая из этих функций выполняет по-разному; MD5 является самым быстрым, а RIPEMD - самый медленный.

MD5 имеет то преимущество, что он вписывается во встроенный тип Guid. Что делает его очень простым в использовании для идентификации.

MD5 однако уязвим для Таранов, SHA1 также уязвим, но в меньшей степени.

При каких условиях следует использовать какой алгоритм хеширования?

конкретные вопросы, на которые мне действительно интересно получить ответ:

  • нельзя ли доверять MD5? В обычных ситуациях, когда вы используете алгоритм MD5 без злого умысла, и ни одна третья сторона не имеет злого умысла, вы ожидаете каких-либо столкновений (то есть два произвольных байта [], производящих один и тот же хэш)

  • насколько лучше RIPEMD, чем SHA1? (если его лучше) его 5 раз медленнее вычислять, но размер хэша такой же, как SHA1.

  • каковы шансы получить не злонамеренные коллизии при хэшировании имен файлов (или других коротких струны)? (Напр. 2 случайные имена файлов с тем же хэшем MD5) (с MD5 / SHA1 / SHA2xx) в общем, каковы шансы на не злонамеренные столкновения?

Это тест, который я использовал:

    static void TimeAction(string description, int iterations, Action func) {
        var watch = new Stopwatch();
        watch.Start();
        for (int i = 0; i < iterations; i++) {
            func();
        }
        watch.Stop();
        Console.Write(description);
        Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
    }

    static byte[] GetRandomBytes(int count) {
        var bytes = new byte[count];
        (new Random()).NextBytes(bytes);
        return bytes;
    }


    static void Main(string[] args) {

        var md5 = new MD5CryptoServiceProvider();
        var sha1 = new SHA1CryptoServiceProvider();
        var sha256 = new SHA256CryptoServiceProvider();
        var sha384 = new SHA384CryptoServiceProvider();
        var sha512 = new SHA512CryptoServiceProvider();
        var ripemd160 = new RIPEMD160Managed();

        var source = GetRandomBytes(1000 * 1024);

        var algorithms = new Dictionary<string,HashAlgorithm>();
        algorithms["md5"] = md5;
        algorithms["sha1"] = sha1;
        algorithms["sha256"] = sha256;
        algorithms["sha384"] = sha384;
        algorithms["sha512"] = sha512;
        algorithms["ripemd160"] = ripemd160;

        foreach (var pair in algorithms) {
            Console.WriteLine("Hash Length for {0} is {1}", 
                pair.Key, 
                pair.Value.ComputeHash(source).Length);
        }

        foreach (var pair in algorithms) {
            TimeAction(pair.Key + " calculation", 500, () =>
            {
                pair.Value.ComputeHash(source);
            });
        }

        Console.ReadKey();
    }

9 ответов


в криптографии хэш-функции предоставляют три отдельные функции.

  1. сопротивление столкновения: как трудно кому-то найти два сообщения (любой два сообщения), которые хэшируют то же самое.
  2. Сопротивление Preimage: учитывая хэш, насколько сложно найти другое сообщение, которое хэширует то же самое? Также известный как односторонняя хэш-функция.
  3. второе сопротивление preimage: дали сообщение, найдите другое сообщение, которое хэширует то же самое.

эти свойства связаны, но независимы. Например, сопротивление столкновению подразумевает сопротивление второму образу, но не наоборот. Для любого данного приложения у вас будут разные требования, требующие одного или нескольких из этих свойств. Хэш-функция для защиты паролей на сервере обычно требует только сопротивления preimage, в то время как дайджесты сообщений требуют всех трех.

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

SHA1 имеет недостаток, который позволяет обнаруживать коллизии теоретически намного меньше, чем 2^80 шагов безопасной хэш-функции его длины потребовать. Атака постоянно пересматривается и в настоящее время может быть выполнена в ~2^63 шага - едва ли в пределах текущей области вычисляемости. По этой причине NIST постепенно прекращает использование SHA1, заявив, что семейство SHA2 должно использоваться после 2010 года.

SHA2-это новое семейство хэш-функций, созданных после SHA1. В настоящее время нет известных атак на функции SHA2. SHA256, 384 и 512 все часть семьи SHA2, как раз используя различные ключевые длины.

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

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


Все хэш-функции "сломаны"

на принципу Дирихле говорит, что старайтесь изо всех сил, вы не можете поместиться больше, чем 2 голубей в 2 отверстия (если вы не режете голубей). Точно так же вы не можете поместить 2^128 + 1 номера в 2^128 слотов. Все хэш-функции приводят к хэшу конечного размера, это означает, что вы всегда можете найти столкновение, если вы ищете последовательности "конечного размера" + 1. Это просто невозможно сделать. Не MD5 и не Лялька.

MD5 / SHA1/Sha2xx не имеют случайных столкновений

все хэш-функции имеют коллизии, это факт жизни. Попадание на эти столкновения случайно эквивалентно победу в межгалактической лотерее. То есть, никто не выигрывает в межгалактической лотерее, Ее просто не так, как работает лотерея. Вы никогда не столкнетесь с случайным хэшем MD5/SHA1/SHA2XXX. Каждое слово в каждом словаре, в каждом язык, хэши к другому значению. Каждое имя пути на каждой машине на всей планете имеет другой хэш MD5/SHA1/SHA2XXX. Откуда мне знать, спросите вы. Как я уже говорил, никто никогда не выигрывает в межгалактической лотерее.

Но... MD5-это сломанный

иногда тот факт, что его сломали не важно.

Как это нет pre-image или второй pre-image атаки на MD5.

Так вы можете спросить, что так сломано в MD5? Третья сторона может генерировать 2 сообщения, одно из которых является злым, а другое-хорошим, что оба хэша имеют одинаковое значение. (атака столкновения)

тем не менее, Текущая рекомендация RSA не использовать MD5, если вам нужно сопротивление предварительного изображения. Люди склонны ошибаться в сторону осторожности, когда дело доходит до алгоритмов безопасности.

Итак, какую хэш-функцию я должен использовать в .NET?

  • используйте MD5, если вам нужна скорость / размер и не заботитесь о нападениях на день рождения или атаках до изображения.

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

имейте в виду, что не все алгоритмы должны защищаться от атак предварительного изображения или столкновения. Возьмите тривиальный случай первого поиска дубликатов файлов на вашем HD.

  • используйте функцию на основе SHA2XX, если вы хотите криптографически безопасную хэш-функцию.

никто никогда не находил столкновения SHA512. КОГДА-ЛИБО. Они очень старались. Если на то пошло, никто никогда не находил столкновения SHA256 или 384. .

  • не используйте SHA1 или RIPEMD, если это не для сценария совместимости.

RIPMED не получил такого же количества проверки, что SHAX и MD5 получили. SHA1 и RIPEMD уязвимы для атак на день рождения. Они оба медленнее, чем MD5 на .NET, и имеют неудобный размер 20 байт. Бессмысленно использовать эти функции, забудьте о них.

SHA1 атаки столкновения до 2^52, его не будет слишком долго, пока Столкновения SHA1 происходят в дикой природе.

для получения актуальной информации о различных хэш-функциях посмотрите на хэш-функция zoo.

Но подождите, есть больше

имеющего быстро хэш-функция может быть проклятием. Например: очень распространенным использованием хэш-функций является хранение паролей. По сути, вы вычисляете хэш пароля в сочетании с известной случайной строкой (чтобы препятствовать атакам rainbow) и сохраняете этот хэш в база данных.

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

чтобы обойти эту проблему,bcrypt алгоритм может быть использован, он разработан, чтобы быть медленным, поэтому злоумышленник будет сильно замедлен, если атакует систему с помощью bcrypt. Недавно скрипт сделал некоторый заголовок и считается некоторыми более эффективным, чем bcrypt, но я не знаю о реализации .Net.


обновление:

времена изменились, у нас есть победитель SHA3. Я бы рекомендовал использовать keccak (Он же SHA3) победитель конкурса SHA3.

Оригинальный Ответ:

в порядке от слабого к сильному я бы сказал:

  1. RIPEMD сломан, никогда не должен использоваться как видно из этого pdf
  2. сломанный МД-5, никогда не должен быть использован,можно сломать в 2 минутах с ноутбуком
  3. SHA-1 сломан, никогда не должен использоваться,нарушается в принципе, атаки становятся лучше к неделе
  4. SHA-2 слабый, вероятно, будет сломан в ближайшие несколько лет. было обнаружено несколько слабых мест. обратите внимание, что, как правило, чем выше размер ключа, тем сложнее сломать хэш-функцию. Хотя key size = strength не всегда верно, это в основном верно. Таким образом, SHA-256, вероятно, слабее, чем SHA-512.
  5. моток не известен Слабости,является кандидатом на SHA-3. Он довольно новый и поэтому непроверенный. он был реализован на нескольких языках.
  6. MD6 нет известных слабостей, является еще одним кандидатом на SHA-3. Вероятно, сильнее, чем Шиен, но медленнее на одноядерных машинах. Как и Шиен, он непроверен. Некоторые безопасности мыслящие разработчики используют его в критически важные роли.

лично я бы использовал MD6, потому что никогда не может быть слишком параноидальный. Если скорость-настоящая проблема, я бы посмотрел на Skein или SHA-256.


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


Я хотел бы перезвонить (до того, как md5 будет разорван), что я все еще широко использую md5, несмотря на его подавляющую сломанность для многих крипто.

пока вы не заботитесь о защите от столкновений (вы все еще можете использовать md5 в hmac), и вы хотите скорость (иногда вы хотите более медленный хэш), то вы все еще можете использовать md5 уверенно.


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


было бы неплохо взглянуть на BLAKE2 алгоритм.

как описано, это быстрее, чем MD5 и, по крайней мере, так же безопасно, как SHA-3. Он также используется несколько программных приложений, включая WinRar.


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


вот мои предложения для вас:

  1. вы, вероятно, должны забыть MD5, если вы предвидите атаки. Их много радужные таблицы для них онлайн, и такие корпорации, как RIAA, как известно, могут производить последовательности с эквивалентными хэшами.
  2. использовать соль если вы можете. Включение длины сообщения в сообщение может затруднить создание полезного хэш-столкновения.
  3. как правило, больше бит означает меньше столкновений (по принципу ячейки) и медленнее, и, возможно, более безопасным (если вы не математический гений, который может найти уязвимости).

см. здесь документ с описанием алгоритма создания столкновений md5 за 31 секунду с настольным компьютером Intel P4.

http://eprint.iacr.org/2006/105