Урок по треку Безопасность приложений 8 мин

Криптография на практике: пароли, TLS, HMAC и JWT

Хеширование паролей, симметричное и асимметричное шифрование, HMAC, TLS, случайность и ловушки JWT.

От AppSec-инженера не ждут, что он изобретёт шифр. Ждут, что он знает, какой готовый примитив выбрать, и видит типичные ошибки применения. Главное правило: не писать свою криптографию, а правильно использовать проверенные библиотеки.

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

Пароль нельзя хранить ни открыто, ни зашифрованным (ключ утечёт вместе с базой), ни быстрым хешем (MD5, SHA-256): видеокарта перебирает миллиарды быстрых хешей в секунду. Нужен медленный хеш с солью:

  • Argon2id: рекомендация OWASP по умолчанию; настраиваются память, число проходов, параллелизм (например 19 МиБ, 2 прохода, 1 поток как минимальная конфигурация).
  • scrypt: тоже требует памяти.
  • bcrypt: проверенный временем, cost 10 и выше; учитывает только первые 72 байта пароля.
  • PBKDF2 с HMAC-SHA256 и большим числом итераций (порядка 600 тысяч), когда нужна сертифицированная криптография.

Соль уникальна для каждого пароля и хранится рядом с хешем: она делает бесполезными радужные таблицы и не даёт увидеть одинаковые пароли. Перец (pepper) это дополнительный секрет вне базы, например в HSM или KMS. Параметры храните вместе с хешем, чтобы со временем усиливать их и перехешировать при входе.

Шифрование

  • Симметричное: один ключ. Стандарт AES-GCM или ChaCha20-Poly1305: это AEAD, шифрование плюс проверка целостности. Nonce (IV) никогда не повторяется с тем же ключом: повтор nonce в GCM катастрофичен.
  • Режим ECB нельзя: одинаковые блоки дают одинаковый шифртекст. CBC без MAC уязвим к padding oracle.
  • Асимметричное: пара ключей. Для шифрования и обмена ключами (RSA-OAEP, ECDH), для подписи (Ed25519, ECDSA, RSA-PSS).
  • Шифрование не даёт целостности само по себе: без MAC или AEAD шифртекст можно подменить.

Хеш, HMAC и подпись

  • Хеш (SHA-256, SHA-3): отпечаток данных, без ключа. Защищает от случайного повреждения, но не от подмены: атакующий пересчитает хеш.
  • HMAC: хеш с секретным ключом. Проверяет, что сообщение создал владелец ключа (вебхуки, подписанные cookie). Строить MAC как sha256(key + message) нельзя из-за атаки удлинения сообщения.
  • Подпись: асимметрично, проверить может любой с публичным ключом.
  • Сравнивать MAC и токены за постоянное время (hmac.compare_digest, crypto.timingSafeEqual), иначе по времени ответа можно подобрать значение побайтно.

Случайность

Для токенов, ключей, nonce используют криптографический генератор: secrets в Python, crypto.randomBytes и crypto.randomUUID в Node, SecureRandom в Java. Math.random, random и java.util.Random предсказуемы.

TLS

  • Используем TLS 1.2 и 1.3, версии 1.0 и 1.1 официально выведены из употребления.
  • HSTS (Strict-Transport-Security) запрещает браузеру ходить по HTTP после первого визита.
  • Проверка сертификата в клиентах обязательна: verify=False и rejectUnauthorized: false превращают TLS в декорацию.
  • Внутри периметра тоже шифруем: mTLS между сервисами, TLS до базы.

JWT: ловушки

JWT это base64url(header).base64url(payload).подпись. Payload не зашифрован, его прочитает любой.

  • alg: none: токен без подписи. Библиотека должна принимать только явно заданный список алгоритмов.
  • Путаница алгоритмов: сервер ждёт RS256, атакующий присылает HS256 и подписывает токен публичным ключом как HMAC-секретом. Если библиотека берёт алгоритм из заголовка, подпись сойдётся.
  • Слабый секрет HS256 перебирается офлайн по любому перехваченному токену.
  • Нет проверки exp, aud, iss: токен от другого сервиса или просроченный принимается.
  • kid, jku, x5u из заголовка: путь к файлу или URL ключа под контролем атакующего.
  • Отзыв: JWT нельзя отозвать до истечения без серверного списка, поэтому access-токены живут минуты, а refresh-токены ротируются.
  • Декодирование без проверки (jwt.decode(..., verify=False), jwt.decode вместо jwt.verify в Node) частая ошибка в коде.

Частые ошибки

  • MD5 или SHA-256 для паролей.
  • Свой «простой» шифр или XOR.
  • Фиксированный IV, ECB, ключ в коде.
  • Сравнение подписи через ==.
  • verify=False «временно».

Что спросят на собесе

  • Как правильно хранить пароли и зачем соль.
  • Чем HMAC отличается от хеша и от подписи.
  • Что такое атака путаницы алгоритмов в JWT.
  • Почему важен уникальный nonce в AES-GCM.
  • Что даёт HSTS.
  • Как отозвать JWT.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.