Яку криптографічну хеш-функцію слід вибрати?


137

.NET Framework поставляється з 6 різними алгоритмами хешування:

  • MD5: 16 байт (час хешування 500 МБ: 1462 мс)
  • SHA-1: 20 байт (1644 мс)
  • SHA256: 32 байти (5618 мс)
  • SHA384: 48 байт (3839 мс)
  • SHA512: 64 байти (3820 мс)
  • RIPEMD: 20 байт (7066 мс)

Кожна з цих функцій виконує по-різному; MD5 є найшвидшим, а RIPEMD - найповільнішим.

MD5 має ту перевагу, що він вписується у вбудований тип Guid; і це основа типу 3 UUID . Хеш SHA-1 є основою UUID типу 5. Що робить їх дійсно простими у використанні для ідентифікації.

Однак MD5 вразливий до атак зіткнення , SHA-1 також вразливий, але меншою мірою.

За яких умов я повинен використовувати алгоритм хешування?

Особливі запитання, на які мені дуже цікаво відповісти:

  • Не можна довіряти 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();
    }

15
Той факт, що ви згадуєте, що md5 вписується у формат GUID (16 байт), говорить про принципове непорозуміння. Не гарантується, що хеш є унікальним, але він є рідкісним (і важко підробити, якщо він використовується в криптографічному сенсі) і походить з того, про що він є хеш, а GUID - це унікальний, але не пов'язаний зі змістом річ, яку він ідентифікує. Вони використовуються для самих різних цілей.
Barry Wark

1
Виправте його незв’язаний факт, його просто зручний факт реалізації конкретного факту. Я розумію, що не можна вписати нескінченність у 16 ​​байт. Ви можете зіткнутися з будь-яким алгоритмом хешуваннявання
Сем Сафрон

5
Крім того, Посібник просто унікальний на практиці, якщо теоретично ви продовжуєте створювати Guids, ви отримаєте дублікати.
Сам Шафран

3
Ви дійсно не повинні вкладати хеш у GUID, навіть якщо він підходить. Найпростіший приклад: дві копії одного і того ж файлу повинні мати різні GUID, але однаковий хеш. Перші 8 літер імені людини також непогано вписуються в 16 байт.
dbkk

2
@ user2332868 Поломка SHA-1 не впливає на ймовірність випадкових зіткнень. Коли шкідливий намір є загрозою для вашого використання, я думаю, що сліпо підбирати будь-яку хеш-функцію неправильно, і вам потрібно витратити час на аналіз ризику / витрат для вашого конкретного випадку.
Андрій Таранцов

Відповіді:


138

У криптографії хеш-функції забезпечують три окремі функції.

  1. Опір зіткненням : як важко комусь знайти два повідомлення ( будь-які два повідомлення), які мають однакові хеши.
  2. Опір попереднього зображення : Дано хеш, наскільки важко знайти ще одне повідомлення, яке хеширує те саме? Також відомий як одностороння хеш-функція .
  3. Опір попереднього зображення : надавши повідомлення, знайдіть інше повідомлення, яке має те ж саме.

Ці властивості пов'язані, але незалежні. Наприклад, опір зіткнення передбачає другий опір попереднього зображення, але не навпаки. Для будь-якого додатка у вас будуть різні вимоги, потребуючи однієї або декількох з цих властивостей. Хеш-функція для захисту паролів на сервері зазвичай вимагає лише попереднього опору, тоді як для дайджестів повідомлень потрібні всі три.

Було показано, що MD5 не є стійким до зіткнення, але це не виключає його використання в додатках, які не потребують стійкості до зіткнення. Дійсно, MD5 все ще використовується в додатках, де вигідні менший розмір клавіш та швидкість. Зважаючи на це, через свої недоліки дослідники рекомендують використовувати інші хеш-функції в нових сценаріях.

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

SHA2 - це нове сімейство хеш-функцій, створене після SHA1. Наразі невідомі напади на функції SHA2. SHA256, 384 та 512 - це частина сімейства SHA2, просто використовуючи різну довжину ключів.

RIPEMD Я не можу занадто багато коментувати, за винятком зазначення, що це не так часто використовується, як сімейства SHA, і тому дослідники криптографічних досліджень не були ретельно вивчені. Саме тому я рекомендував би використовувати функції SHA над ним. У використанні, яке ви використовуєте, це здається досить повільним, що робить його менш корисним.

На закінчення, немає жодної найкращої функції - все залежить від того, для чого вона вам потрібна. Пам’ятайте про недоліки кожного з них, і ви зможете найкраще вибрати правильний хеш-функцію для свого сценарію.


1
Дуже вдячний, що заглиблюєтесь у цей рівень деталізації. Це дуже корисно.
joelc

1
Для деяких додатків може бути доречною навіть хеш-функція, яка не має криптовалюти. ОП ніколи не згадувало, чи було це спеціально для паролів, або для автентичного реагування на відповідь, або для маркерів доступу, або просто для індексації ряду рядків / файлів. Виступ, з іншого боку, викликає занепокоєння в рамках ОП ...
Сева Алексєєва

111

Усі хеш-функції "зламані"

Принцип закуток каже , що спробувати так складно , як ви не можете відповідати більш 2 голубів в 2 -х отворів (якщо не вирізати голубів вгору). Так само ви не можете помістити 2 ^ 128 + 1 числа в 2 ^ 128 слотів. Усі хеш-функції призводять до хеша кінцевого розміру, це означає, що ви завжди зможете знайти зіткнення, якщо провести пошук через "послідовність обмеженого розміру" + 1. Це просто неможливо зробити. Не для MD5 і не для Skein .

MD5 / SHA1 / Sha2xx не мають шансів зіткнутись

Усі хеш-функції мають зіткнення, це факт життя. Випадкові ці зіткнення випадково є рівнозначним виграшу міжгалактичної лотереї . Тобто, міжгалактична лотерея ніхто не виграє , це просто не те, як працює лотерея. Ви не зіткнетеся з випадковим хешем MD5 / SHA1 / SHA2XXX, ВСІХ. Кожне слово в кожному словнику, в кожній мові має різну цінність. Кожна назва шляху, на кожній машині всієї планети має різний хеш MD5 / SHA1 / SHA2XXX. Як я це знаю, ви можете запитати. Ну, як я вже говорив раніше, ніхто не виграє міжгалактичну лотерею.

Але ... MD5 зламаний

Іноді те, що її зламано, не має значення .

На даний момент немає відомих попередніх зображень або атак попереднього зображення на MD5.

Отже, що так порушено у MD5, можете запитати? Третя сторона може генерувати 2 повідомлення, одне з яких EVIL, а інше - ДОБРЕ, що обидва хешують однакове значення. ( Атака зіткнення )

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

Отже, яку функцію хешу я повинен використовувати в .NET?

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

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

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

  • Використовуйте функцію на основі SHA2XX, якщо ви хочете криптографічно захищену хеш-функцію.

Ніхто ніколи не виявив жодного зіткнення SHA512. ВСЕ. Вони дуже старалися. З цього приводу ніхто ніколи не виявив зіткнення SHA256 або 384. .

  • Не використовуйте SHA1 або RIPEMD, якщо це не для сценарію сумісності.

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

Атаки зіткнення SHA1 знижуються до рівня 2 ^ 52, але це не буде занадто довго, поки зіткнення SHA1 не вийдуть на природу.

Для отримання актуальної інформації про різні хеш-функції дивіться зоопарк хеш-функцій .

Але чекайте, є більше

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

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

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


Незважаючи на те, що і MD5, і SHA-1 були ослаблені, MD5 набагато слабкіше, ніж SHA-1, хоча лише трохи швидше. Фактичні зіткнення MD5 були знайдені та використані для реальної експлуатації (підробка сертифікатів CA), але, наскільки я знаю, фактичних зіткнень SHA-1 не знайдено (хоча кількість операцій значно зменшилася від грубої сили). І враховуючи, наскільки слабкіший MD5, я не здивуюся, якби повторні атаки з'явилися швидше для MD5, ніж для SHA-1. Таким чином, я думаю, ви повинні використовувати SHA-1, якщо вам потрібна швидкість, а не опір зіткнення, інакше використовувати один із сімейства SHA-2.
Брайан Кемпбелл

1
@Brian досить ясно, що протягом наступних кількох років люди зможуть запускати атаки зіткнення на SHA1, це ефективно зробить SHA1 настільки ж корисним, як і MD5. Справа сертифіката CA - це атака зіткнення, аналогічно через кілька років люди зможуть здійснити ту саму атаку на сертифікати SHA1 CA. Атака залежить від злісної сторони, яка створює ЗЛИВ та ДОБРИЙ сертифікат. Невідомі напади приматів на MD5 і той факт, що є атаки зіткнення, не робить напади попереднього зображення більш-менш вірогідними.
Сем Шафран

Це набагато менше, який хеш ви використовуєте для паролів, ніж це те, що хешируйте. Якщо ваша сіль відома, то ваша база даних негайно вразлива для атаки словника; якщо ваша сіль є процедурною, а ваша файлова система порушена, ви (знову) вразливі; якщо ваша сіль відпущена, ви знову ставите під загрозу. Проблема безпеки - незалежно від того, ЩО хеширується. Сертифікати я не звертатимусь, тому що я не розглядав їх як програміст (IE, створення, розуміння тощо).
Роберт К

Термін "зламаний" має специфічне значення в контексті хешування, і це не саме значення, на яке ця відповідь наголошує. Вся ця відповідь буде викликати плутанину.
Джоел МакБет

1
Це відмінна відповідь, тому що вона зосереджена на практичності. Хеші використовуються для речей, крім захисту (наприклад, для генерування ключів пошуку кешу для нечутливих даних або визначення, чи змінився серіалізований об'єкт). Шанси цілеспрямованої атаки практично нульові (ніколи не кажіть ніколи), і навіть якби атака вдалася, це не мало б істотного впливу. Відмінна робота, зосереджена на практичному (замість теоретичному) впливі.
DVK

35

Оновлення:

Часи змінилися, у нас є переможець SHA3. Я б рекомендував використовувати переможця конкурсу SHA3 ​​keccak (він же SHA3 ).

Оригінальний відповідь:

Для найслабшого до найсильнішого я б сказав:

  1. RIPEMD BROKEN, Ніколи не повинен використовуватися, як це видно в цьому PDF-файлі
  2. MD-5 BROKEN, Ніколи не використовуватися, може бути зламаний за 2 хвилини з ноутбуком
  3. SHA-1 BROKEN, Ніколи не застосовується, він руйнується в принципі, атаки стають кращими з тижня
  4. SHA-2 слабкий, ймовірно, буде порушено в найближчі кілька років. Виявлено кілька слабких місць. Зауважте, що чим більше розмір клавіш, тим важче зламати хеш-функцію. Хоча розмір ключа = сила не завжди відповідає дійсності, він здебільшого відповідає дійсності. Тож SHA-256, ймовірно, слабший, ніж SHA-512.
  5. Скейн НЕ ЗНАЄТЬСЯ СЛАБІСТЬ, є кандидатом на SHA-3 . Він досить новий і, таким чином, не перевірений. Він реалізований на купі мов.
  6. MD6 НЕ ЗНАЄТЬСЯ СЛАБІСТЬ, є ще одним кандидатом на SHA-3. Можливо, сильніше, ніж Скіен, але повільніше на одноядерних машинах. Як і Скіен, це неперевірено. Деякі розробники, орієнтовані на безпеку, використовують його у вирішальних ролях місії .

Особисто я б користувався MD6, тому що ніхто ніколи не може бути занадто параноїчним. Якщо швидкість викликає справжнє занепокоєння, я б подивився на Скейна, або на SHA-256.


5
Я не став би Skein та MD6 так високо в списку; є причина, що змагання SHA-3 не завершиться до кінця 2012 року. Потрібно багато часу і багато очей, щоб переконатися, що хеш-функція насправді може бути захищеною, і жодна з цих функцій існували досить довго для цього ще.
Ерік Бернетт

Я погоджуюся з вашими настроями, але я думаю, що громада знаходиться в дивному становищі. Усі використовувані хеш-функції небезпечно близькі до зламу (можливо, можливо, не SHA2 256-512), і все ж нам доведеться чекати до 2012 року, щоб вибрати заміну. вибирайте свою отруту: слабку / зламану чи неперевірену (більшість кандидатів у НІСТ не публікуються більше 6 місяців)? Важкий вибір.
Етан Хайльман

5
RIPEMD зламаний, але RIPEMD-128/160/256 різні, а не зламані.
Bwooce

Мені невідомі якісь виконавські реалізації Skein для .NET. Я натрапив на SkeinFish і nskein, і обидва були дуже повільними.
Cocowalla

1
Я б зачекав з використанням SHA-3, поки фактичний стандарт не з’явиться там, принаймні, якщо ви хочете насправді слідувати стандарту. Сам алгоритм має занадто багато варіантів.
Paŭlo Ebermann

3

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


1
Хоча я аж ніяк не є експертом у цій галузі, чи не є близьким до можливості обчислити довільні хеші MD5 грубою силою в наш час?
мафу

@mafu: Пізня відповідь тут, але можна обчислити будь-який хеш за допомогою грубої сили. Це може зайняти дуже довго.
Warty

@ItzWarty Я конкретно мав на увазі необхідний час - оскільки MD5 досить короткий, я вважав, що можливо просто закинути на нього розумне обчислювальне джерело (E3, або дешеву комп'ютерну сітку, кілька машин з кількома відеокартами, щось уздовж цих ліній) і мати можливість обчислити довільний хеш MD5 протягом, скажімо, кількох днів.
mafu

@mafu Атака попереднього зображення коштує 2 ^ 127 викликів хешу для 128-бітного хеша. Це далеко не можливо. 2 ^ 80 викликів можливо, але вже дуже дорого.
CodesInChaos

2

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


1
Багато разів, коли обговорювали рішення проблеми, я згадую, що я використовую MD5 для швидкої ідентичності (хешування рядка), вони кажуть "але md5 зламаний ... не використовуй його, використовуй sha1" ... Я дійсно не підписуюся на це було цікаво якщо що-небудь настільки принципово зламано з більш слабкими хешами, що їх слід уникати ... наприклад, справжні випадки, коли звичайні дані створюють зіткнення
Сем Сафрон

Бачачи, як MD5 працював чудово для мільйонів людей протягом п'ятнадцяти років, я підозрюю, що це нормально для вас, якщо безпека хешу не є вирішальною.
mqp

2
@sambo MD5 працює чудово майже в будь-якому випадку, за винятком випадків, коли фактична безпека / цілісність вашої системи залежить від запобігання зіткнень.
Rex M

2

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

Поки ви не переймаєтеся захистом від зіткнень (ви все ще безпечні для використання md5 в hmac), і ви хочете швидкості (іноді хочете повільніший хеш), тоді ви все одно можете використовувати md5 впевнено.


@Mike Я з вами з цього приводу, це було те, що я копав з цим питанням, це щось про слабкіші хеш-функції, настільки принципово порушені, що їх ніколи не слід використовувати.
Сем Шафран

На додаток до цього, якщо дані або необхідна безпека даних мають тривалість життя коротший, ніж період тріщини (на декілька хвилин у цей день iirc), MD5 абсолютно нормально. Ситуаційно корисна, але все ж корисна справа.
annakata

@annakata - Пам’ятайте, що вам також доведеться уникати повторного використання клавіш у кількох повідомленнях, щоб воно було корисним за таких обставин.
Стів Вестбрук

2

Було б гарною ідеєю поглянути на алгоритм BLAKE2 .

Як описано, він швидший, ніж MD5 і принаймні настільки ж безпечний, як SHA-3. Він також реалізований декількома програмними програмами , включаючи WinRar.


Це може бути швидше, за винятком того, що багато реалізацій мають апаратну підтримку, що робить SHA-256 досить швидким.
зап

Я згоден. станом на 2019 рік, Blake2b - найкращий хеш загального призначення, випущений на сьогоднішній день. Значно швидше, ніж усі інші альтернативи, і не менш захищений (не принаймні будь-який змістовний спосіб), і його можна виконати лише в 336 байт оперативної пам’яті (168 для blake2s), о, і він оптимізований для процесорів з малоцінністю, що є домінуючий ендіан в сучасних системах.
hanshenrik

0

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


1
Хеш-функції зазвичай не використовують клавіші
Етан Хайльман

0

Ось мої пропозиції для вас:

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

Дивіться тут документ, в якому детально описується алгоритм для створення зіткнень md5 за 31 секунду з настільним комп'ютером Intel P4.

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


Цей коментар дуже старий і здається досить похованим, але цей біт - RIAA, як відомо, змогли створювати послідовності з рівноцінними хешами, - вискакував на мене, і мені дуже цікаво, який був контекст для цього. Зокрема, жорстокі дії MD5 8 років тому були трохи менш тривіальними, ніж це було у 2017 році, тому вони, мабуть, мали досить вагомі причини.
i336_
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.