Что такое хеширование?

Ответ

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

Критически важные свойства криптографических хеш-функций:

  1. Детерминированность: Один и тот же вход всегда дает одинаковый хеш.
  2. Быстрота вычисления: Хеш от данных вычисляется за приемлемое время.
  3. Необратимость (стойкость к прообразу): По значению хеша практически невозможно восстановить исходные данные.
  4. Устойчивость к коллизиям: Крайне мала вероятность, что два разных входа дадут одинаковый хеш.
  5. Лавинный эффект: Малейшее изменение во входных данных (один бит) полностью меняет выходной хеш.

Применение в разработке на PHP:

  • Хранение паролей: Никогда не храните пароли в открытом виде или с использованием устаревших функций (md5, sha1). Используйте password_hash() и password_verify().
    
    // Безопасное хеширование пароля
    $plainPassword = 'mySecretPass123!';
    $hash = password_hash($plainPassword, PASSWORD_DEFAULT); // Использует bcrypt или argon2i
    // $hash выглядит как: '$2y$10$...' и содержит соль (salt) и параметры алгоритма.

// Сохраняем $hash в базу данных.

// Проверка пароля при логине $userInputPassword = $_POST['password']; $hashFromDb = '...'; // Получаем из БД if (password_verify($userInputPassword, $hashFromDb)) { // Пароль верный if (password_needs_rehash($hashFromDb, PASSWORD_DEFAULT)) { // Если параметры алгоритма устарели, перехешируем и обновляем в БД. $newHash = password_hash($userInputPassword, PASSWORD_DEFAULT); // save $newHash to DB } } else { // Неверный пароль }


*   **Проверка целостности данных:** Хеш-суммы файлов (например, `md5_file()`, `sha1_file()`) для проверки, что файл не был поврежден при передаче.
*   **Структуры данных:** Хеш-таблицы (в PHP — ассоциативные массивы) используют хеш-функцию для быстрого доступа к элементам по ключу.
*   **Цифровые подписи и HMAC:** Для проверки подлинности и целостности сообщений.

Ответ 18+ 🔞

А, хеширование! Ну это ж, бля, основа основ, как хлеб с маслом. Сейчас на пальцах объясню, а то некоторые думают, что это какая-то магия, ёпта.

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

Теперь, почему это пиздато и где подводные камни? Слушай сюда, главные правила, без которых всё накрывается медным тазом:

  1. Один и тот же вход — один и тот же фарш. Всегда. Это аксиома, блядь.
  2. Сделать фарш должно быть быстро. Не часами же его молоть.
  3. А вот из фарша обратно слона не собрать. Вообще. Это называется необратимость. Если функция этому правилу не соответствует — это не хеш, а манда с ушами, выкидывай её нахуй.
  4. Коллизии — это пиздец. Коллизия — это когда из разного говна получается внешне одинаковый фарш. В хорошей функции вероятность этого — овердохуища малая.
  5. Лавинный эффект. Изменил в исходнике одну букву — весь хеш должен поменяться до неузнаваемости. Если поменялось только пару символов — функция говно, доверия к ней ебать ноль.

А теперь, блядь, самое важное — как этим пользоваться в PHP, чтобы не облажаться.

Запомни раз и навсегда, как «Отче наш»: ПАРОЛИ ХЕШИРУЕМ ТОЛЬКО ЧЕРЕЗ password_hash()! Никаких md5() и sha1()! Это уже не просто устарело, это, блядь, прям приглашение для всяких пидарасов шерстяных тебе в базу залезть. Эти старые функции считаются ебанько слабыми уже лет десять как.

Смотри, как правильно, чтобы волнение ебать было нулевое:

// Допустим, пользователь зарегался и ввёл пароль
$plainPassword = 'mySecretPass123!';
// Херачим его в надёжный хеш. PASSWORD_DEFAULT — умный, сам выберет лучший алгоритм (сейчас это bcrypt)
$hash = password_hash($plainPassword, PASSWORD_DEFAULT);
// В $hash теперь не просто хеш, а целая паспарту: и сам хеш, и соль (salt), и сложность. Выглядит типа '$2y$10$n8b7g6v5h4j3k2l1...'
// Эту строку — в базу и забыл.

// Теперь пользователь логинится
$userInputPassword = $_POST['password'];
$hashFromDb = '...'; // Достаём из базы наш сохранённый хеш

// Магия проверки
if (password_verify($userInputPassword, $hashFromDb)) {
    // Всё, вошли! Пароль сошёлся.
    // Но тут ещё одна хитрая жопа есть: алгоритмы стареют. Надо проверить, не пора ли перехешировать поновее.
    if (password_needs_rehash($hashFromDb, PASSWORD_DEFAULT)) {
        $newHash = password_hash($userInputPassword, PASSWORD_DEFAULT);
        // И обновляем запись в базе этим новым хешом
    }
} else {
    // Не, ну тут всё ясно — пошёл нахуй, неправильный пароль.
}

Видишь, как красиво? password_verify() сама разберёт тот старый хеш, достанет оттуда соль и параметры, и сверит. Тебе вообще париться не надо.

Где ещё это годится?

  • Целостность файлов. Скачал ты с какого-то левого сайта дистрибутив. Рядом лежит файлик MD5SUMS. Берёшь md5_file('distr.iso') и сравниваешь. Сошлось — значит, по дороге не кривые руки что-то подменили. Не сошлось — тут тебе и хиросима, и нигерсраки, качай заново.
  • Ассоциативные массивы. Да-да, внутри PHP они — огромные хеш-таблицы, чтобы быстро искать по ключу. Это уже под капотом, но знать приятно.
  • HMAC. Это когда нужно не просто хеш сделать, а ещё и секретным ключом подпереть, чтобы проверить, что сообщение именно от тебя пришло, а не от какого-то левого чувака. Но это уже тема для отдельного разговора, а то у меня терпения ноль ебать, и так инфы дохуя.

Короче, суть уловил? Хеширование — не для шифрования, а для «отпечатка». Сделал отпечаток, сохранил. Потом принёс данные — сделал отпечаток заново, сравнил. Сошлось — значит, те же самые данные. Всё, блядь, просто как три копейки. Главное — инструменты правильные используй, а не старьё, которое уже все взломали вдоль и поперёк.