Чому хеш-значення MD5 не є оборотними?


91

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

Якщо на моєму сервері, у PHP я видаю:

md5("stackoverflow.com") = "d0cc85b26f2ceb8714b978e07def4f6e"

Коли ви запускаєте той самий рядок через функцію MD5, ви отримуєте той самий результат при встановленні PHP. Процес використовується для отримання деякої вартості з деякої вихідної вартості.

Чи не означає це, що існує якийсь спосіб деконструювати те, що відбувається, і змінити хеш-значення?

Що саме в цих функціях робить результуючі рядки неможливими?


54
Наприклад, простим прикладом незворотного значення є модуль. Наприклад, 10% 3 = 1, але ви не можете змінити значення 1 на 10, оскільки це також може бути 4
Gab Royer

57
Якби ви змогли реконструювати дані, у вас був би найефективніший алгоритм стиснення без втрат коли-небудь :)
Dan Diplo

Відповіді:


204

Вхідний матеріал може мати нескінченну довжину, де вихідний результат завжди має довжину 128 біт. Це означає, що нескінченна кількість вхідних рядків буде генерувати однакові результати.

Якщо вибрати випадкове число і розділити його на 2, але записати лише залишок, ви отримаєте або 0, або 1 - парне або непарне відповідно. Чи можна взяти це 0 або 1 і отримати оригінальне число?


4
Тобто ні число -> залишок, ні рядок -> md5 не є «ін’єкційними функціями».
Федеріко А. Рампоні

Федеріко, ви, звичайно, маєте на увазі, що бієктивні функції також не є? Вони обидва ін’єкційні.
Mihai Limbășan

10
moocha: ін'єкційний означає 1 до 1. MD5, безумовно, не 1 до 1, оскільки домен більший за діапазон. Ще один момент, на який варто звернути увагу, полягає в тому, що з урахуванням контрольної суми MD5 дуже важко знайти навіть один рядок, який до нього хешує. Можливо, варто додати до відповіді для уточнення.
біоцинк

4
Неможливо мати хеш-функцію, яка генерує унікальні значення. Ви відображаєте нескінченну кількість значень у кінцеву кількість значень, що гарантує зіткнення.
Cody Brocious

4
Я б припустив, що ваша відповідь не стосується ключового моменту. Як уже згадувалось biozinc, для безпечного хешу паролів важливо, що ви не можете знайти жодного вхідного сигналу, який створює вихідні дані, не те, що ви не можете знайти оригінальний вхід. З огляду на це, MD5 не обов’язково настільки безпечний, як може бути ( en.wikipedia.org/wiki/MD5#Collision_vulnerabilities ).
Mike Pelley

53

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


9
подумайте, як швидко було б завантажити дистрибутиви Linux, якби замість цього можна було просто отримати md5 :)
Колін Пікард

15
@Colin Pickard: ми більше не будемо завантажувати дистрибутиви Linux, ми будемо їх записувати . :)
tzot

29

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

Розглянемо цю функцію (у позначенні PHP як запитання):

function simple_hash($input) {
     return bin2hex(substr(str_pad($input, 16), 0, 16));
}

Це додає деякі пробіли, якщо рядок занадто короткий, а потім приймає перші 16 байт рядка, а потім кодує його як шістнадцяткове. Він має такий самий розмір виводу, як хеш MD5 (32 шістнадцяткові символи, або 16 байт, якщо опустити частину bin2hex).

print simple_hash("stackoverflow.com");

Це виведе:

737461636b6f766572666c6f772e636f6d

Ця функція також має ту саму властивість неін'єктивності, яку підкреслює відповідь Коді для MD5: Ми можемо передавати рядки будь-якого розміру (якщо вони поміщаються в наш комп'ютер), і вона видасть лише 32 шістнадцяткові цифри. Звичайно, це не може бути ін’єкційним.

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

Важливими припущеннями для криптографічної хеш-функції є:

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

Очевидно, що моя simple_hashфункція не виконує жодної з цих умов. (Насправді, якщо ми обмежимо вхідний простір "16-байтовими рядками", тоді моя функція стає ін'єктивною і, отже, навіть доказується стійкою до другої зображення та стійкою до зіткнень.)

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

Щоб відповісти на актуальне запитання:

Що саме в цих функціях робить результуючі рядки неможливими?

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

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

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


4
Так, я знаю, що це досить пізня відповідь, але прийнята відповідь не повинна залишатися такою.
Paŭlo Ebermann

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

(продовження ...) 2. Ці пояснення використовують "Математику", щоб показати фундаментальну проблему, через яку такі операції втрачають інформацію та стають незворотними.
Автодиктакт

1
@SandeepDatta Я додав кілька абзаців про це.
Paŭlo Ebermann

1
Хоча інші відповіді в цій темі є більш технічно правильними, ця відповідь є найбільш корисною. Неін'єктивна функція f (x) = 1 не оборотна, але нецікава. Корисність хешування полягає в опорі перед зображеннями, де важко знайти будь-який вхід, що дає конкретний результат.
Джастін Дж. Старк,

18

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


12

MD5 не створює унікального хеш-значення; метою MD5 є швидке отримання значення, яке суттєво змінюється на основі незначної зміни джерела.

Наприклад,

"hello" -> "1ab53"
"Hello" -> "993LB"
"ZR#!RELSIEKF" -> "1ab53"

(Очевидно, що це не фактичне шифрування MD5)

Більшість хешів (якщо не всі) також не є унікальними; швидше, вони досить унікальні , тому зіткнення дуже малоймовірне, але все ж можливе.


8

Хороший спосіб думати про хеш-алгоритм - це думати про зменшення розміру зображення у Photoshop ... скажімо, у вас є зображення розміром 5000x5000 пікселів, а потім ви змінюєте його розмір до 32x32. У вас все ще є зображення вихідного зображення, але воно набагато менше і фактично "викидає" певні частини даних зображення, щоб воно помістилося в менший розмір. Отже, якщо вам потрібно було змінити розмір цього зображення розміром 32x32 до 5000x5000, все, що ви отримаєте, - це розмитий безлад. Однак оскільки зображення розміром 32x32 не настільки велике, теоретично можна було б передбачити зменшення розміру іншого зображення для отримання таких самих пікселів!

Це просто аналогія, але вона допомагає зрозуміти, що робить хеш.


3
Незважаючи на те, що зміна розміру зображення є процесом з втратами, все одно досить легко створити зображення в оригінальному розмірі 5000 × 5000, яке (при повторному застосуванні функції усадки) зменшиться до того самого зображення 32 × 32. Знайти таку прообраз має бути важко для хорошої хеш-функції.
Paŭlo Ebermann

4

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


1
Є 365 можливих значень дня народження, тобто від 2 ^ 8 до 2 ^ 9. 128-бітний хеш має 2 ^ 128 можливих значень - у 2 ^ 120 разів більше. Так, зіткнення є більш імовірними, ніж ви можете інтуїтивно зрозуміти, але вони все одно астрономічно малоймовірні.
Тім Кітінг

Вам знадобиться приблизно 2 ^ 64 різних значень, щоб мати хороші шанси на зіткнення хешу. Все ще досить багато.
Paŭlo Ebermann

4

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

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

Ці критерії іноді використовують:

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

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

Число 3 означає число 2.

Що стосується, зокрема, MD5, виявилося, що він має недоліки: як зламати MD5 та інші хеш-функції .


2

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

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


Ага, так. Мені сподобалось читати пост Джеффа на Hash Tables ( codinghorror.com/blog/archives/000949.html ), і ця тема допомогла у розумінні концепції.
barfoon


1

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

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


1

Найкращий спосіб зрозуміти, що означали всі найбільш голосовані відповіді, - це насправді спробувати повернути алгоритм MD5. Я пам’ятаю, що намагався повернути те повідомлення, яке в початковому повідомленні мене вбило. Мені довелося створити не тільки дійсне початкове повідомлення, але і засолене дійсне початкове повідомлення, чого я ніколи не міг зробити. Але знання, отримані в результаті цього експерименту, були приємними. , кілька років тому алгоритм MD5crypt не для відновлення вихідного повідомлення, оскільки це явно неможливо, а просто для створення повідомлення, яке дало б такий самий хеш, що і вихідний хеш. Це, принаймні теоретично, дало б мені спосіб входу на пристрій Linux, який зберігав користувача: пароль у файлі / etc / passwd, використовуючи сформоване повідомлення (пароль) замість використання оригінального. Оскільки в обох повідомленнях буде однаковий хеш, система визнає мій пароль (згенерований з вихідного хешу) дійсним. Це взагалі не спрацювало. Через кілька тижнів, якщо я добре пам'ятаю, використання солі


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

0

за визначенням функція хеш (криптографічний хеш): не повинна бути оберненою; не повинна мати зіткнень (найменш можливо).

реєструйте своє запитання: це односторонній хеш. вхід (незалежно від довжини) буде генерувати вихід фіксованого розміру (він буде заповнений на основі алгоритму (512-бітна межа для MD5)). Інформація стискається (втрачається) і практично неможливо генерувати за допомогою зворотних перетворень.

додаткова інформація про MD5: він вразливий до зіткнень. нещодавно переглядав цю статтю, http://www.win.tue.nl/hashclash/Nostradamus/

відкриває вихідний код для реалізації крипто-хешу (MD5 та SHA) можна знайти в коді Mozilla. (бібліотека freebl).


0

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

Наприклад, спробуйте наступний хеш-код на http://gdataonline.com/seekhash.php, щоб дізнатись, який текст я використовував для обчислення хешу

aea23489ce3aa9b6406ebb28e0cda430

Ах, так, хеш загальноприйнятого 7-літерного слова. Тепер використовуйте його, щоб зрозуміти цю лірику пісні з 11 слів із пробілами та пунктуацією: 9f2c08d4e6158bd4854b15be50c8daa8. До зустрічі через кілька тисячоліть.
Тім Кітінг

6fba2bbab8a8366309bf67c7df12c622? Підказка: це може бути OEM-версія конкретної версії Mac OS X!
scherand

@Tim Keating, @scherand: Просто вказуючи на слабкість хеш-алгоритмів, оскільки хеш рядка завжди однаковий, нам не обов'язково потрібно зламати алгоритм, щоб з'ясувати фактичний рядок.
Бабар,

2
Але це не те, що ти сказав. Ви сказали, що хеші "попередньо обчислюються для всіх можливих рядків і зберігаються для зручного доступу", що є явно помилковим (набір "усіх можливих рядків" нескінченний ... і навіть набір "усіх правдоподібних рядків" насправді дуже великий ). IMHO це спотворює, наскільки легко здійснити атаку за словником проти розумної парольної фрази.
Тім Кітінг,

0

f (x) = 1 є незворотним. Хеш-функції не є незворотними.

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

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

Однак це ігнорує, що розумний відкритий текст, отриманий із насіння, passwordє набагато, набагато більш імовірним, ніж інший, створений насіннямWsg5Nm^bkI4EgxUOhpAjTmTjO0F!VkWvysS6EEMsIJiTZcvsh@WI$IH$TYqiWvK!%&Ue&nk55ak%BX%9!NnG%32ftud%YkBO$U6o настільки, що з тих, хто стверджує, що це друга можливість, будуть сміятися.

Точно так же, якщо ви намагаєтеся вирішити між двома потенційними паролями passwordі Wsg5Nm^bkI4EgxUO, це не так складно зробити , так як деякі математики б ви вірите.


Де ви берете свої більшість шифрів, просто XOR дані з ключовими знаннями? Це справедливо для потокових шифрів, але існують і блок-шифри, і вони не працюють таким чином.
Paŭlo Ebermann

-5

Мені подобаються всі різні аргументи. Очевидно, що справжня цінність хешованих значень полягає просто у забезпеченні нечитабельними заповнювачами рядків, таких як паролі. Він не має особливих переваг щодо посиленої безпеки. Припускаючи, що зловмисник отримав доступ до таблиці з хешованими паролями, він / вона може:

  • Хеш пароля за власним вибором і розмістіть результати всередині таблиці паролів, якщо він / вона має права писати / редагувати таблицю.
  • Створюйте хешовані значення загальних паролів і перевіряйте наявність подібних хешованих значень у таблиці паролів.

У цьому випадку слабкі паролі не можуть бути захищені одним фактом їх хешування.


Справжня цінність "хешованих цінностей" полягає не в забезпеченні нечитабельними заповнювачами. Якщо "password1" хешовано до "newval", чи все одно це не приховує значення подібним чином, хоча хеш читається та значимий? Крім того, паролі - це ПОРОШИЙ приклад, оскільки вони НІКОЛИ не повинні хешуватися. Якщо припустити, що зловмисник мав доступ до запису до зазначеної бази даних, це, безумовно, є можливістю. Однак, здається, ви просто відкидаєте належне використання таких функцій хешування, один із прикладів викладений у багатьох відповідях вище - цілісність повідомлення. Саме тому я сьогодні в цій темі.
Shane
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.