OTP SMS: двухфакторная аутентификация по одноразовому коду
Если в сервис можно войти по одному паролю — рано или поздно туда зайдёт не тот, кто должен. Пароли утекают через фишинг, повторно используются на десятках сайтов, оказываются в публичных базах после взломов. Любой более или менее заметный сервис обязан добавить второй фактор — что-то, чего у злоумышленника физически нет.
Самый массовый второй фактор сегодня — OTP-код, отправленный по SMS. Пользователь вводит логин и пароль, а на телефон приходит четырёх- или шестизначное число, которое нужно ввести в форму. Просто, понятно, работает на любом телефоне без установки приложений. Поэтому OTP SMS используют банки, маркетплейсы, государственные сервисы, корпоративные системы доступа, операторы связи — везде, где есть привязка пользователя к номеру.
В статье разберём, что такое OTP-код, как устроена двухфакторная аутентификация по SMS, какие требования предъявляются к SMS-шлюзу для отправки кодов, какие риски существуют и как от них защититься, а также чем OTP по SMS отличается от push-уведомлений и TOTP-приложений.
Что такое OTP и как работает аутентификация по SMS
OTP расшифровывается как One-Time Password — одноразовый пароль. Это короткий код, который действует один раз и только в течение нескольких минут после генерации. Если код не ввести вовремя или ввести один раз — он перестаёт работать.
Схема двухфакторной аутентификации по SMS выглядит так. Пользователь вводит логин и пароль на сайте или в приложении. Если связка верная, сервер генерирует случайный код (обычно 4–6 цифр), сохраняет его у себя вместе с идентификатором пользователя и временем создания, и отправляет этот же код в SMS-сообщении на привязанный номер телефона. Пользователь получает SMS, вводит код в форму. Сервер сверяет введённое значение со своим — если совпадает и срок действия не истёк, пользователь авторизован.
Главное в этой схеме — сам факт того, что у злоумышленника есть только украденный пароль. Чтобы войти, ему нужен ещё и доступ к телефону жертвы. Это резко поднимает планку: вместо удалённой атаки по списку паролей нужно физически украсть устройство или перехватить SMS, что несравнимо сложнее.
Где применяется OTP SMS
Двухфакторная аутентификация по SMS прижилась там, где цена ошибки высокая, а пользователи разные по уровню технической подготовки.
Банковский сектор и финтех. Подтверждение входа в личный кабинет, перевода средств, операции с картами, выпуска новой карты, смены пароля. Это самый зарегулированный сегмент — для финансовых сервисов 2FA по SMS не опция, а требование. Большинство крупных банков (включая Т-Банк, Сбер, Альфа) используют OTP по SMS для подтверждения чувствительных операций.
Маркетплейсы и e-commerce. Подтверждение заказа, привязка нового устройства, изменение адреса доставки, восстановление доступа. Чем выше средний чек и популярнее сервис у мошенников, тем плотнее в нём закручены гайки с 2FA.
Корпоративные системы доступа. VPN, CRM, ERP, внутренние порталы. Когда удалённый сотрудник заходит с домашнего ноутбука, одного пароля мало — добавляется SMS-код. Для сотрудников это привычный сценарий, не требующий обучения.
Государственные и муниципальные сервисы. «Госуслуги», личные кабинеты налоговой, ЖКХ, медицинских порталов. Здесь OTP по SMS — единственный реалистичный способ массовой 2FA: TOTP-приложения слишком сложны для возрастной аудитории, а push-уведомления требуют установки приложения.
Регистрация и восстановление доступа. Подтверждение номера при создании аккаунта (одновременно проверяет, что номер реальный и принадлежит пользователю) и сброс пароля по SMS. Сценарий «забыл пароль» полностью завязан на доступ к телефону.
Подтверждение операций. Платежи через интернет-банк, оплата по подписке, операции с большой суммой. SMS-код выступает дополнительной защитой даже после успешного входа в аккаунт.
OTP SMS, push-уведомления и TOTP — что выбирать
Помимо SMS, есть ещё два массовых способа доставки одноразовых кодов: push-уведомления через приложение и TOTP — коды, генерируемые приложением вроде Google Authenticator или Яндекс Ключ. У каждого свои сильные и слабые стороны.
SMS — универсален. Работает на любом телефоне, не требует установки приложений и интернета. Доходит туда, куда не доходит push (например, у пользователя нет нашего приложения). Минусы — задержки при перегрузке сети, риск SIM-swap-атак, зависимость от качества канала оператора. Стоимость одного SMS невелика, но при масштабе в сотни тысяч аутентификаций в день расходы растут.
Push-уведомления работают через приложение сервиса. Они быстрее SMS, бесплатные и защищены от SIM-swap. Но требуют, чтобы у пользователя было установлено приложение, был интернет и push был не запрещён в настройках. Подходит для активной аудитории, плохо работает для редких сценариев входа.
TOTP-приложения — самый безопасный вариант. Код генерируется на устройстве пользователя без передачи через сеть — перехватить его невозможно. Не зависит от связи и оператора. Минус один, но критичный: для большинства пользователей TOTP — слишком сложно. Объяснить «отсканируйте QR-код в Authenticator» аудитории старше 50 практически нереально.
В реальности крупные сервисы комбинируют: SMS как массовый и понятный метод по умолчанию, push для активных пользователей с приложением, TOTP — как опция для технически подкованных. Каждый канал закрывает свою аудиторию.
Как устроена OTP-аутентификация изнутри
Снаружи — вводишь пароль, получаешь SMS, вводишь код. Изнутри происходит несколько важных вещей, от которых зависит безопасность.
Генерация кода. Сервер генерирует случайное число с помощью криптографически стойкого генератора (CSPRNG), а не обычного `rand()`. Длина — обычно 4 или 6 цифр. Шесть цифр дают миллион вариантов и существенно усложняют брутфорс по сравнению с четырьмя (десять тысяч).
Время жизни (TTL). Код действителен в течение короткого окна — стандартно от 3 до 5 минут. После истечения он автоматически инвалидируется. Это ограничивает время, за которое злоумышленнику нужно успеть украсть и использовать код.
Привязка к контексту. Код сохраняется в связке с идентификатором сессии, IP-адресом, fingerprint устройства. Если пользователь начал вход с одного устройства, а пытается ввести код с другого — это повод заблокировать операцию.
Одноразовость. После успешной валидации код удаляется или помечается как использованный. Повторно его применить нельзя, даже если он не истёк по времени.
Хранение. Сами коды никогда не хранятся в открытом виде. Обычно — в виде хеша с солью, либо в кеше в оперативной памяти (Redis, Memcached) с автоматическим TTL.
Аудит. Каждая попытка генерации, отправки и валидации логируется. Это нужно и для разбора инцидентов, и для соответствия нормативным требованиям.
Для бизнеса вся эта механика обычно скрыта за SDK или API провайдера OTP. Но понимать её полезно — чтобы оценивать чужие решения и не наделать ошибок в собственном.
Какие требования предъявляются к SMS-шлюзу для OTP
Не каждый SMS-шлюз подходит для отправки OTP-кодов. Если для маркетинговых рассылок терпимо, что сообщение придёт через минуту, то для OTP минута — это уже катастрофа. Пользователь уйдёт со страницы.
Скорость доставки. Хороший OTP-шлюз доставляет сообщение за секунды. Целевой показатель — медианно до 5–10 секунд от момента отправки до получения. Это достижимо только при прямых договорах с операторами связи, а не через цепочку посредников.
Надёжность канала. OTP — это не та история, где можно потерять сообщение. Шлюз должен быть с многократным резервированием, отказоустойчивой архитектурой и автоматическим переключением на резервные каналы оператора, если основной не отвечает. Любое падение шлюза напрямую означает, что часть пользователей не сможет войти в сервис.
Простой API. OTP интегрируется в форму авторизации, и интеграция должна занимать часы, а не недели. Хороший API — это REST с JSON, понятная документация, готовые библиотеки под основные языки, песочница для тестов без оплаты. Подробнее про требования к SMS API мы разбирали в статье SMS API для разработчиков.
Поддержка тестового окружения. На этапе разработки нужно отправлять тестовые SMS без реальной оплаты и без риска нагрузить продакшен. Полноценный шлюз даёт sandbox с тестовыми номерами и тестовым балансом.
SLA и поддержка. Для OTP важно не только «работает», но и «гарантированно работает». SLA с конкретными числами доступности, поддержка 24/7, понятный процесс эскалации инцидентов — это обязательные пункты при выборе шлюза для критичной аутентификации.
Контроль статусов доставки. Через API должен возвращаться статус каждого сообщения — доставлено, не доставлено, в пути, ошибка. Это позволяет бизнесу понимать, в чём проблема: пользователь ввёл неправильный номер, оператор задерживает, или код вообще не ушёл.
Защита OTP-аутентификации от атак
OTP по SMS — не панацея. У схемы есть известные слабости, и их нужно учитывать в дизайне сервиса.
Rate limiting на отправку кода. Если позволить отправку OTP без ограничений, злоумышленник может закидать жертву сотней SMS подряд — и попутно опустошить баланс сервиса. На стороне сервера должен стоять лимит: не больше N сообщений в M минут на номер и на пользователя.
Ограничение попыток ввода. После 3–5 неудачных попыток ввода кода аккаунт временно блокируется или отправка нового кода замораживается. Иначе шестизначный код брутфорсится за миллион попыток — то есть за несколько минут.
Защита от SIM-swap. Самая известная атака — переоформление SIM-карты жертвы на номер злоумышленника через социальную инженерию в офисе оператора. Защиты на стороне SMS-шлюза от неё нет, но сервис может отслеживать недавнюю смену SIM (некоторые операторы дают API) и требовать дополнительное подтверждение в течение, скажем, 72 часов после такой смены.
Защита от перехвата. Канал между сервером и SMS-шлюзом должен быть зашифрован (HTTPS, TLS). Это исключает перехват кода на промежуточном узле. Сам SMS-канал зашифровать невозможно, но за пределами устройства оператора код увидеть нельзя.
Уведомление пользователя о подозрительной активности. Если на аккаунт пытаются войти из нового места или с нового устройства, кроме OTP должно прийти отдельное уведомление: «Был запрос на вход с такого-то IP, если это не вы — заблокируйте аккаунт».
Не использовать тот же канал для нотификации о смене номера. Если злоумышленник захватил номер, отправка SMS «ваш номер изменили» только подтвердит ему успех. Уведомление должно идти на старый номер, по email, push или в виде звонка с проговариванием кода.
Не отправлять OTP в массовых рассылках вместе с маркетингом. Это техническое требование: маркетинговый трафик идёт другими маршрутами, его задержки и фильтры по операторам не подходят для критичной аутентификации. Транзакционные и маркетинговые SMS — отдельные каналы.
Юридическая сторона: 152-ФЗ и согласие
В России отправка SMS на номер пользователя — обработка персональных данных. Если человек регистрируется в сервисе и оставляет номер для аутентификации, требуется его согласие на обработку. Формально такое согласие даётся при регистрации — пользователь ставит галочку «принимаю политику конфиденциальности», где указано использование номера для OTP.
OTP по SMS относится к транзакционным сообщениям — отправка кода входа не требует отдельного согласия на рекламу. Но это не означает, что можно слать всё подряд: если в OTP-сообщение добавить рекламную фразу, оно автоматически становится рекламным, и требует согласия по 38-ФЗ «О рекламе».
Также важно правильно настроить хранение номеров — отдельные политики уничтожения данных после отзыва согласия, шифрование БД, журналирование доступа. Это не специфика OTP, а общие требования 152-ФЗ, но они применимы и здесь. Подробнее про юридические аспекты SMS-рассылок мы писали в статье Согласие на SMS-рассылку: как правильно собирать и хранить.
Типичные ошибки при внедрении OTP
При сотнях интеграций в год повторяется один и тот же набор косяков. Их полезно знать, чтобы не наступать заново.
Слишком длинный TTL. Видели «срок действия кода — 30 минут». За это время код успеет уйти в спам у злоумышленника, утечь в публичный канал, попасть в логи фронтенда. Правильно — 3–5 минут, максимум 10.
Один и тот же код можно использовать несколько раз. Тестировали с кодом «1234», в продакшен поставили без флага одноразовости. Любой перехватчик может использовать код повторно.
Нет rate limiting на отправку. Атакующий нажимает «Отправить код» в цикле, баланс сервиса опустошается за час, пользователь получает 200 SMS подряд и просит оператора заблокировать наш короткий номер.
Код в URL-параметрах. «Перейдите по ссылке:
Один OTP-код на несколько действий. Сгенерировали код для входа, а пользователь успел нажать «подтвердить платёж» — и подошёл тот же код. Каждое чувствительное действие должно генерировать собственный, независимый код.
Слишком короткий код. Четыре цифры легко брутфорсятся при слабом rate limit. Шесть цифр и нормальный rate limit — стандарт индустрии.
Доверие к Caller ID. Перешли с SMS на голосовое подтверждение, отправляющий номер легко подделать через VoIP — пользователь видит «звонок от банка» и сообщает код мошеннику. Голосовое OTP требует отдельных мер защиты.
Логирование кода. Сам код OTP не должен попадать в логи приложения, в Sentry, в системы мониторинга. Иначе доступ к логам становится доступом ко всем кодам.
Внедрение OTP SMS через Quicktel
Quicktel — российский SMS-агрегатор с прямыми договорами со всеми крупными операторами связи. Это даёт скорость доставки, на которой строится надёжная двухфакторная аутентификация. Мы работаем с банками, маркетплейсами, корпоративными сервисами и SaaS-продуктами, где OTP-аутентификация — критичный сценарий.
Для OTP мы предлагаем REST API с предсказуемыми response-time, статусами доставки в реальном времени, веб-хуками о финальном статусе, тестовой средой и SLA на доступность. Интеграция занимает день у среднего разработчика — есть готовая документация, примеры на основных языках и поддержка, которая отвечает на технические вопросы. Полное описание API доступно на странице SMS API (HTTP).
Если у вас уже есть CRM или собственная авторизация, мы подключаемся как backend для отправки сообщений — без переделки клиентской части. Если нужна готовая логика 2FA с генерацией кодов и валидацией — обсудим отдельно, такие сценарии тоже реализуем.
Чтобы оценить нашу скорость и качество доставки, можно начать с бесплатных тестовых SMS. Это лучший способ понять, подходит ли наш канал под ваши требования, не подписывая ничего и не интегрируясь полноценно. Связаться с командой Quicktel — на странице контактов.