← Назад к вопросам

На чем основан Scram

1.3 Junior🔥 122 комментариев
#Методологии и фреймворки

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Scram (Salted Challenge Response Authentication Mechanism)

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

Ключевые принципы и основа Scram

Scram построен на нескольких фундаментальных концепциях:

  1. Защита от перехвата пароля: Клиент никогда не передает пароль серверу в чистом виде. Вместо этого используются производные значения (ключи), вычисленные из пароля.
  2. Использование соли (salt): Для каждого пароля генерируется уникальная случайная строка — соль. Она предотвращает атаки с использованием радужных таблиц, поскольку хэш одного и того же пароля с разной солью будет разным. Соль хранится на сервере открыто вместе с учетными данными.
  3. Взаимная аутентификация (Mutual Authentication): В процессе участвует и сервер, доказывая клиенту, что он также обладает данными, производными от правильного пароля. Это защищает от атак с подменой сервера.
  4. Защита от повторного воспроизведения (Replay Attack): Механизм использует уникальные нонсы (nonce) от клиента и сервера, что делает каждый сеанс аутентификации уникальным.
  5. Итеративное хэширование: Пароль, соль и другие данные многократно обрабатываются криптографической функцией (например, SHA-256). Это увеличивает сложность подбора пароля методом грубой силы.

Базовый протокол обмена сообщениями (на примере SCRAM-SHA-256)

Протокол состоит из нескольких шагов, обмен сообщениями можно представить так:

Клиент -> Сервер: `client_first_message` (содержит nonceC)
Сервер -> Клиент: `server_first_message` (содержит nonceS, salt, iteration count)
Клиент -> Сервер: `client_final_message` (содержит вычисленное доказательство ClientProof)
Сервер -> Клиент: `server_final_message` (содержит вычисленное доказательство ServerSignature для проверки сервера)

Детали криптографических вычислений

Этап 1: Подготовка (Регистрация/Настройка учетной записи) На этом этапе сервер создает и сохраняет учетные данные пользователя.

# Псевдокод для этапа подготовки на стороне сервера
import hashlib, os, binascii, hmac

def create_scram_credentials(password):
    # 1. Генерация уникальной случайной соли
    salt = os.urandom(16)  # 16 байт
    iterations = 4096      # Рекомендуемое количество итераций

    # 2. Вычисление ключа аутентификации
    # Сначала вычисляется ключ PBKDF2 из пароля и соли
    salted_password = hashlib.pbkdf2_hmac(
        'sha256',
        password.encode('utf-8'),
        salt,
        iterations
    )

    # 3. Вычисление ключей для клиента и сервера
    # Используется функция HMAC для генерации производных ключей
    client_key = hmac.new(salted_password, b"Client Key", hashlib.sha256).digest()
    server_key = hmac.new(salted_password, b"Server Key", hashlib.sha256).digest()

    # 4. Сохранение верификатора (stored key)
    stored_key = hashlib.sha256(client_key).digest()  # Это хранится вместо пароля

    # Сервер сохраняет: имя пользователя, salt, iterations, stored_key, server_key
    credentials = {
        'salt': binascii.hexlify(salt).decode(),
        'iterations': iterations,
        'stored_key': binascii.hexlify(stored_key).decode(),
        'server_key': binascii.hexlify(server_key).decode()
    }
    return credentials

Этап 2: Процесс аутентификации

  • Клиент вычисляет те же salted_password, client_key, stored_key, что и сервер при регистрации.
  • Затем клиент генерирует ClientProof, который является результатом XOR между client_key и ClientSignature. Сервер, имея stored_key, может независимо вычислить ClientSignature и, выполнив операцию XOR с полученным ClientProof, восстановить client_key. Хэш восстановленного client_key должен совпасть с сохраненным stored_key. Это доказывает знание пароля.
  • Сервер вычисляет ServerSignature с помощью HMAC от server_key и отправляемых данных. Клиент, зная правильный пароль, может вычислить ожидаемую подпись и сверить ее с полученной. Это доказывает клиенту, что сервер знает server_key.

Преимущества Scram

  • Безопасность: Устойчив к перехвату, пассивному прослушиванию, replay-атакам и подмене сервера.
  • Стандартизация: Определен в RFC 5802 и RFC 7677, что обеспечивает совместимость между различными системами (например, PostgreSQL, MongoDB, RabbitMQ, XMPP).
  • Гибкость: Поддерживает различные хэш-функции (SCRAM-SHA-1, SCRAM-SHA-256, SCRAM-SHA-512).
  • Отсутствие необходимости в обратимом хранении паролей: Сервер хранит только производные ключи и соль.

Таким образом, Scram основан на комбинации проверенных криптографических примитивов: PBKDF2 для укрепления пароля, HMAC для создания ключей и доказательств, и соли для защиты от предвычисленных атак. Этот механизм представляет собой надежный компромисс между безопасностью, стандартизацией и практической реализуемости, что делает его отличным выбором для аутентификации в современных распределенных системах и базах данных.

На чем основан Scram | PrepBro