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

Ответ

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

Ключевые свойства:

  1. Детерминированность (Determinism): Один и тот же ввод всегда даёт один и тот же хеш.

  2. Необратимость (Pre-image resistance): По известному хешу практически невозможно восстановить исходные данные. Это свойство критически важно для хранения паролей.

  3. Стойкость к коллизиям (Collision resistance): Практически невозможно найти два разных набора входных данных, которые бы давали одинаковый хеш. Это важно для проверки целостности данных.

  4. Лавинный эффект (Avalanche effect): Минимальное изменение во входных данных (например, одного бита) приводит к кардинальному, непредсказуемому изменению хеша.

  5. Высокая скорость вычисления: Хеш должен вычисляться быстро для любого объёма данных.

Примеры использования в бэкенде:

  • Хранение паролей: В базе данных хранятся не сами пароли, а их хеши (часто с "солью" — случайной строкой, уникальной для каждого пользователя).
  • Проверка целостности данных: Для проверки того, что файл или сообщение не были изменены при передаче, можно сравнить хеш оригинала с хешем полученных данных.
  • Ключи в структурах данных: Хеш-функции (не обязательно криптографические) лежат в основе map в Go для быстрого доступа к элементам.
  • Кэширование: Хеш от URL-адреса и параметров запроса может использоваться в качестве ключа для кэширования ответа.
  • Цифровые подписи: Хеш документа подписывается приватным ключом для подтверждения авторства и неизменности.

Пример хеширования в Go (SHA-256):

package main

import (
    "crypto/sha256"
    "fmt"
)

func main() {
    data := []byte("hello, backend!")

    // Вычисляем хеш
    hash := sha256.Sum256(data)

    // Выводим хеш в виде шестнадцатеричной строки
    fmt.Printf("%xn", hash)
}

Ответ 18+ 🔞

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

И что она умеет, эта твоя мясорубка?

  1. Детерминированность: Это как с водкой, чувак. Один и тот же огурец, закинутый в одну и ту же банку, всегда даст один и тот же рассол. И с хешом так же — один и те же данные на входе = один и тот же хеш на выходе. Никаких сюрпризов.

  2. Необратимость: А вот это, сука, самое главное! Это как попытаться из котлеты восстановить, блядь, целую корову. По хешу нельзя понять, что было на входе. Именно поэтому пароли в базах хранят в виде хешей, а не в открытую, как дурачки. Иначе любой долбоёб, доставший базу, всех твоих пользователей по полочкам разложит.

  3. Стойкость к коллизиям: Это значит, что практически невозможно найти два РАЗНЫХ куска данных, которые на выходе дадут ОДИН И ТОТ ЖЕ хеш. Представь, ты подписываешь договор на миллион, а злоумышленник находит другой текст, который даёт такую же подпись. Пиздец, да? Вот чтобы этого не было.

  4. Лавинный эффект: Это вообще песня! Изменишь в исходных данных хоть одну запятую, одну буковку — и хеш меняется настолько пиздецки кардинально, что связи между старым и новым не найдёшь, даже если обосрёшься. Как будто взрыв, ёпта.

  5. Скорость: Ну и, понятное дело, ждать, пока эта мясорубка пережуёт гигабайты логов, никто не будет. Всё должно работать быстро, как по маслу.

И где это всё, блядь, применяется?

  • Пароли: Я уже говорил. Не храним пароли, храним их хеши, да ещё и с "солью" (это такая случайная приправа для каждого пользователя, чтобы одинаковые пароли выглядели по-разному).
  • Целостность данных: Скачал ты файл, вычислил его хеш и сравнил с тем, что на сайте написали. Совпало? Значит, никто по дороге не подменил тебе в архив порнухи. Не совпало? Качай заново, тебя наебали.
  • Внутри map в Go: Да-да, обычные map тоже на хешах работают, чтобы быстро ключи искать. Правда, там функции попроще.
  • Кэширование: Сделал хеш от URL и параметров запроса — вот тебе и идеальный ключ для кэша. Короткий и уникальный.
  • Цифровые подписи: Сначала от документа делают хеш (быстро и коротко), а потом уже этот хеш подписывают секретным ключом. Экономия времени и места — овердохуищная.

Ну и как это выглядит в коде, на Go? Да элементарно, Ватсон!

package main

import (
    "crypto/sha256"
    "fmt"
)

func main() {
    data := []byte("hello, backend!") // Суём в мясорубку нашу фразу

    // Крутим ручку мясорубки (вычисляем хеш)
    hash := sha256.Sum256(data)

    // Смотрим, что на выходе получилось (в шестнадцатеричном виде)
    fmt.Printf("%xn", hash)
}

Запустишь — и тебе вывалится эта самая строчка, уникальный отпечаток твоих данных. Красота, блядь! Всё гениальное просто, как три копейки.