Что такое хеширование и где оно применяется в бэкенде?

Ответ

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

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

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

Основные области применения в бэкенде:

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

Пример криптографического хеширования (SHA-256) в Go:

package main

import (
    "crypto/sha256"
    "fmt"
)

func main() {
    data := []byte("hello world")

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

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