Перейти к содержимому
Toova
Все инструменты

MD5 против SHA-256 против SHA-512 — хеш-функции: объяснение

Toova

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

MD5 скомпрометирован. SHA-1 устарел. SHA-256 и SHA-512 в настоящее время безопасны. SHA-3 существует для тех, кто думает о перспективе. Но «скомпрометирован» означает разное в разных контекстах — MD5 вполне пригоден в одних ситуациях и катастрофически неприемлем в других. В этом руководстве объясняются ключевые свойства, как каждая функция им соответствует, и предлагается чёткая система принятия решений для выбора правильного хеша в 2026 году.

Что такое хеш-функция

Криптографическая хеш-функция отображает ввод произвольной длины в вывод фиксированной длины (дайджест или хеш). Три свойства определяют криптографически стойкую хеш-функцию:

  • Стойкость к восстановлению прообраза — по заданному хешу h вычислительно невозможно найти входное значение m такое, что hash(m) = h. Это свойство «односторонности».
  • Стойкость ко второму прообразу — по заданному входному значению m1 невозможно найти другое входное значение m2 такое, что hash(m1) = hash(m2).
  • Стойкость к коллизиям — невозможно найти любые два разных входных значения m1 и m2 такие, что hash(m1) = hash(m2).

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

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

Ввод:   "hello"
MD5:    5d41402abc4b2a76b9719d911017c592  (128 бит / 32 шест. символа)

Ввод:   "Hello"
MD5:    8b1a9953c4611296a827abf8c47804d7  (один символ изменён — вывод полностью другой)

MD5 — быстрый, повсеместный и скомпрометированный

История и конструкция

MD5 (Message Digest 5) разработан Роном Ривестом в 1991 году и создаёт 128-битный (16-байтный) дайджест. На протяжении большей части 1990-х годов он был стандартным выбором для проверки целостности файлов, подписания сертификатов и хеширования паролей. Он чрезвычайно быстр — современный процессор может вычислять десятки миллионов хешей MD5 в секунду, а GPU — миллиарды.

Почему MD5 скомпрометирован

В 2004 году Сяоюнь Ван с коллегами продемонстрировали практическую атаку на коллизию MD5 — два разных файла, дающих одинаковый MD5-хеш. Атака выполняется за минуты на потребительском оборудовании. В 2008 году исследователи создали поддельный сертификат удостоверяющего центра с использованием коллизии MD5, показав уязвимость реальной инфраструктуры PKI. В 2012 году вредоносная программа Flame использовала коллизию MD5 для подделки сертификата подписи кода Microsoft.

NIST официально объявил MD5 устаревшим для большинства криптографических целей. Удостоверяющие центры прекратили выдавать сертификаты с подписью MD5 к 2009 году. Производители браузеров убрали поддержку подписей сертификатов MD5 приблизительно в 2011 году.

Когда MD5 всё ещё допустим

MD5 не лишён какой-либо практической ценности. Для контрольных сумм, не связанных с безопасностью — обнаружения случайного повреждения данных при передаче файлов, адресации на основе содержимого в системе кеширования, где злоумышленник не может повлиять на входные данные, или генерации уникальных идентификаторов в закрытой внутренней системе — MD5 остаётся приемлемым. Ключевой тест: если злоумышленник может извлечь пользу из создания коллизии, не используйте MD5. Если важны только случайные повреждения, MD5 вполне подходит.

  • Безопасно: внутренняя дедупликация, ключи кеша, обнаружение изменений файлов без требований безопасности
  • Небезопасно: сертификаты, цифровые подписи, хеширование паролей, проверка подлинности файлов, токены безопасности

SHA-1 — устарел, но ещё встречается

SHA-1 создаёт 160-битный дайджест и стал преемником MD5. На протяжении большей части 2000-х годов он оставался стандартом для подписания сертификатов и кода. В 2017 году атака SHAttered продемонстрировала первую практическую коллизию SHA-1, создав два разных PDF-файла с одинаковыми хешами SHA-1, используя около 110 GPU-лет вычислений — дорого, но в рамках бюджетов государственных структур и всё более доступно.

SHA-1 признан устаревшим NIST и всеми крупными удостоверяющими центрами. Его не следует использовать для сертификатов, подписания кода или каких-либо новых приложений, критичных с точки зрения безопасности. Некоторые устаревшие системы по-прежнему используют SHA-1 внутренне, но настоятельно рекомендуется перейти на SHA-256. Git по-прежнему использует SHA-1 для адресации объектов (хотя переход на SHA-256 ведётся), но это постепенно прекращается.

SHA-256 — действующий стандарт

SHA-256 входит в семейство SHA-2, разработанное АНБ и стандартизированное NIST в FIPS 180-4. Он создаёт 256-битный (32-байтный) дайджест. SHA-256 интенсивно исследуется с момента публикации в 2001 году, и ни одной практической атаки обнаружено не было. Это де-факто стандарт для:

  • TLS-сертификатов (практически все сертификаты, выдаваемые сегодня, используют SHA-256)
  • Подписания кода (Windows Authenticode, нотаризация Apple, JAR-файлы)
  • HMAC-SHA256 для аутентификации API (AWS Signature v4, верификация вебхуков GitHub)
  • Подписей токенов JWT (HS256 и RS256 оба используют SHA-256 внутри)
  • Идентификаторов транзакций блокчейна (Bitcoin использует двойной SHA-256)
  • Проверки целостности файлов в менеджерах пакетов (npm, pip, apt)
Ввод:    "hello"
SHA-256: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
         (256 бит / 64 шест. символа)

SHA-512: 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d
         99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
         (512 бит / 128 шест. символов)

Производительность SHA-256

SHA-256 использует внутренние 32-битные операции со словами. На 32-битном оборудовании или более старых процессорах без аппаратного ускорения он заметно медленнее MD5. На современных 64-битных процессорах с расширениями SHA (Intel Goldmont+, AMD Zen+, Apple Silicon, ARM Cortex-A57+) SHA-256 аппаратно ускорен и чрезвычайно быстр — нередко приближаясь к скоростям MD5. В большинстве серверных сред есть аппаратное ускорение, поэтому на практике SHA-256 достаточно быстр для практически любых приложений.

SHA-512 — шире и порой быстрее

SHA-512 создаёт 512-битный (64-байтный) дайджест, используя внутренние 64-битные операции со словами. На 64-битном оборудовании без расширений SHA он может оказаться быстрее SHA-256, поскольку его 64-битные операции лучше используют современную ширину регистров. На оборудовании с расширениями SHA, как правило, быстрее SHA-256, поскольку расширения оптимизированы именно под него.

SHA-512 обеспечивает больший запас безопасности — 256-битную стойкость к коллизиям против 128-битной у SHA-256. Для большинства современных моделей угроз 128-битная стойкость SHA-256 к коллизиям более чем достаточна (взлом потребует порядка 2^128 операций). SHA-512 уместен в следующих случаях:

  • Вы ориентируетесь на 64-битные серверы и хотите максимальной пропускной способности без аппаратных расширений
  • Вам нужны более длинные дайджесты в качестве ключевого материала для других криптографических операций
  • Вы хотите дополнительный запас безопасности для данных, которые должны оставаться защищёнными на протяжении десятилетий
  • Вы реализуете протоколы, специально требующие SHA-512 (например, некоторые наборы шифров TLS)

SHA-384 и SHA-512/256

SHA-384 — усечённая версия SHA-512, создающая 384 бита: удобна, когда нужны 64-битные внутренние операции SHA-512, но требуется более короткий вывод. SHA-512/256 — ещё один усечённый вариант, дающий 256-битный вывод с использованием внутренних вычислений SHA-512. SHA-512/256 устойчив к атакам расширения длины, которым подвержен SHA-256, что делает его полезным в контекстах, где расширение длины вызывает озабоченность (хотя HMAC уже нейтрализует это в большинстве практических сценариев).

SHA-3 — другая архитектура, устойчивость к будущим угрозам

SHA-3 (стандартизирован в NIST FIPS 202, 2015) использует губчатую конструкцию Keccak — принципиально иной дизайн по сравнению со структурой Merkle-Damgard, применяемой в SHA-2. Это важно, потому что любая будущая слабость, обнаруженная в конструкции Merkle-Damgard, одновременно затронет MD5, SHA-1 и SHA-2, тогда как SHA-3 остался бы незатронутым.

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

Таблица сравнения

Алгоритм Вывод Стойкость к коллизиям Статус Скорость (ПО) Для паролей?
MD5 128 бит Скомпрометирован Устарел Очень быстрый Никогда
SHA-1 160 бит Скомпрометирован Устарел Быстрый Никогда
SHA-256 256 бит 128 бит Действующий стандарт Быстрый (аппаратное ускор.) Никогда (слишком быстрый)
SHA-512 512 бит 256 бит Безопасен Быстрый на 64-бит Никогда (слишком быстрый)
SHA-3-256 256 бит 128 бит Устойчив к будущим угрозам Умеренный (ПО) Никогда (слишком быстрый)
bcrypt 60-символьная строка Н/П Только для паролей Намеренно медленный Да

Хеширование паролей: совершенно другая задача

Это заслуживает отдельного раздела, потому что является одной из наиболее распространённых ошибок разработчиков. SHA-256 — правильный инструмент для проверки целостности файлов, подписания API и верификации сертификатов. Для хеширования паролей он неприемлем, и его применение в этих целях приводит к реальным инцидентам безопасности.

Проблема в скорости. SHA-256 разработан с расчётом на быстроту — современный GPU может вычислять миллиарды хешей SHA-256 в секунду. Злоумышленник, получивший базу данных хешированных паролей, может перебирать миллиарды вариантов в секунду. Даже длинный случайный пароль можно быстро взломать, если хеш быстрый.

// НИКОГДА не делайте это для паролей
const hash = crypto.createHash('sha256').update(password).digest('hex');
// Для паролей используйте bcrypt, scrypt или Argon2
const bcrypt = require('bcrypt');
const hash = await bcrypt.hash(password, 12);  // коэффициент сложности 12

Инструмент Bcrypt Test позволяет хешировать и проверять bcrypt-пароли прямо в браузере. Для понимания коэффициентов сложности bcrypt и соответствующего им времени вычисления это полезный справочник при настройке рабочего коэффициента приложения.

HMAC: добавление аутентификации к хешу

Обычный хеш не доказывает, кто его вычислил — любой, у кого есть данные, может вычислить тот же SHA-256. HMAC (Hash-based Message Authentication Code) добавляет секретный ключ к вычислению, создавая тег, который может воспроизвести только тот, кто знает ключ. HMAC-SHA256 — стандарт для:

  • Верификации подписей вебхуков (GitHub, Stripe, Shopify используют HMAC-SHA256)
  • AWS Signature Version 4 (подписание запросов)
  • Токенов JWT HS256 (HMAC-SHA256 от заголовка + полезной нагрузки)
  • Целостности cookie (подписание куки сессии для предотвращения подделки)
const crypto = require('crypto');

// Подписываем сообщение с помощью HMAC-SHA256
const mac = crypto
  .createHmac('sha256', secretKey)
  .update(message)
  .digest('hex');

// Проверка: сравниваем за постоянное время (защита от атак по времени)
const isValid = crypto.timingSafeEqual(
  Buffer.from(mac, 'hex'),
  Buffer.from(received, 'hex')
);

Обратите внимание на использование timingSafeEqual для сравнения. Сравнение значений MAC с помощью обычной проверки равенства строк раскрывает информацию о времени, которую можно использовать в атаках по времени. Всегда применяйте функцию сравнения с постоянным временем выполнения при верификации MAC. Воспользуйтесь генератором HMAC для вычисления значений HMAC-SHA256 при тестировании и отладке без написания кода.

Практические рекомендации

Общая проверка целостности файлов (контрольные суммы)

Используйте SHA-256. Это стандарт для проверки пакетов (файлы npm lockfile, хеши требований pip, слои образов Docker). Инструмент SHA-256 Hash вычисляет SHA-256 дайджесты прямо в браузере для текстового ввода или строковых значений. Для быстрых контрольных сумм без требований безопасности, где критична скорость и источник вы контролируете, MD5 остаётся приемлемым, но SHA-256 предпочтительнее в любом совместном или автоматизированном контексте.

TLS-сертификаты и подписание кода

SHA-256 — обязательный стандарт. Все удостоверяющие центры выдают сертификаты SHA-256. Никогда не используйте MD5 или SHA-1 для новых сертификатов — они будут отклонены современными браузерами и операционными системами.

Аутентификация API

Используйте HMAC-SHA256. Это устоявшийся стандарт, хорошо поддерживаемый во всех языках и ожидаемый большинством документации по безопасности API. Вычисляйте дайджесты с помощью инструмента MD5 Hash или SHA-256 Hash для быстрых сравнений, а HMAC-подписи генерируйте с помощью генератора HMAC.

Хеширование паролей

Используйте bcrypt (коэффициент сложности 12+), scrypt или Argon2id. Никогда не применяйте MD5, SHA-1, SHA-256 или SHA-512 напрямую для паролей, даже с солингом. Инструмент Bcrypt Test поможет вам проверять bcrypt-хеши в процессе разработки.

Долгосрочные данные, требующие безопасности на десятилетия

Предпочтительны SHA-512 или SHA-3-256. Больший размер дайджеста обеспечивает дополнительный запас при достижениях в криптоанализе. NIST рекомендует SHA-512 и SHA-3 для приложений, требующих долгосрочной безопасности. Официальную спецификацию алгоритмов SHA-2 смотрите в NIST FIPS 180-4.

Новые системы без ограничений, связанных с обратной совместимостью

SHA-256 для общего применения. Argon2id для паролей. HMAC-SHA256 для кодов аутентификации. Если вы хотите устойчивости к будущим угрозам и можете принять несколько более низкую производительность, SHA-3-256 — надёжная альтернатива SHA-256 для хеширования общего назначения.