Почему одного пароля недостаточно
Пользователь криптобиржи потерял доступ к аккаунту из-за SIM-swap — злоумышленник перевыпустил сим-карту и перехватил SMS с кодом. Счёт был опустошён за 15 минут. Мы столкнулись с этим на одном из проектов: клиент потерял $200 000, потому что двухфакторка была привязана к SMS. После этого мы встроили TOTP 2FA во все криптоприложения, которые разрабатываем.
TOTP (Time-based One-Time Password, RFC 6238) — стандарт, который реализуют Google Authenticator, Authy и большинство корпоративных 2FA-приложений. Для криптоприложения это обязательный минимум: SMS-коды перехватываются через SIM-swap, TOTP — нет. Мы гарантируем, что наша реализация защищает от этих атак.
Как работает TOTP
Алгоритм: HMAC-SHA1 от текущего времени (окно 30 секунд) и shared secret. Shared secret генерируется при настройке 2FA и хранится и на сервере, и у пользователя (в authenticator-приложении). Никакой сетевой передачи при каждой аутентификации — только проверка вычисленного кода.
На backend верификация через популярные библиотеки: pyotp (Python), otplib (Node.js), google-authenticator (Java). На мобильном клиенте код вводится вручную из authenticator-приложения — никакой дополнительной логики TOTP не нужно. TOTP работает в 10 раз быстрее push-уведомлений, так как не требует интернет-соединения.
Почему TOTP безопаснее SMS и push-уведомлений?
| Параметр | TOTP | SMS | Push-уведомление |
|---|---|---|---|
| Зависимость от сети | Нет | Да | Да |
| Уязвимость к фишингу | Низкая | Средняя | Высокая |
| Стоимость для разработчика | Бесплатно | Оплата оператору | Бесплатно |
| Удобство для пользователя | Среднее | Высокое | Высокое |
| Безопасность при SIM-swap | Абсолютная | Нулевая | Зависит от дисплея |
TOTP — золотой стандарт для финансовых приложений. Push-уведомления могут быть перехвачены malware на устройстве, SMS — через SIM-swap. TOTP требует физического доступа к устройству с authenticator-приложением. OWASP рекомендует TOTP для защиты критических аккаунтов.
Встраивание 2FA в процесс входа
Классический flow: логин/пароль → проверка на backend → если у пользователя активна 2FA, backend возвращает промежуточный токен → мобильный показывает экран ввода TOTP → backend верифицирует код и выдаёт полноценный JWT.
sealed class LoginState { object Idle : LoginState() object Loading : LoginState() data class TwoFactorRequired(val tempToken: String) : LoginState() data class Success(val authToken: String) : LoginState() data class Error(val message: String) : LoginState() } class LoginViewModel(private val authRepository: AuthRepository) : ViewModel() { val state = MutableStateFlow<LoginState>(LoginState.Idle) fun submitTOTP(code: String, tempToken: String) { viewModelScope.launch { state.value = LoginState.Loading authRepository.verifyTOTP(code, tempToken) .onSuccess { token -> state.value = LoginState.Success(token) } .onFailure { e -> state.value = LoginState.Error( if (e is InvalidCodeException) "Неверный код" else "Ошибка сервера" ) } } } } Как настроить 2FA: пошаговая инструкция
- Пользователь инициирует настройку 2FA в профиле.
- Backend генерирует shared secret и QR-URI
otpauth://totp/.... - Мобильное приложение отображает QR-код (на Android —
zxing-android-embedded, на iOS —CoreImage.CIFilter.qrCodeGenerator) и текстовый secret для ручного ввода. - Пользователь сканирует QR с помощью Google Authenticator или Authy.
- Для верификации пользователь вводит первый сгенерированный код.
- Backend проверяет код и активирует 2FA.
- После активации генерируются 8-10 одноразовых backup-кодов, которые отображаются на экране с опцией копирования или скачивания.
Backup-коды: что это и зачем нужны?
Без backup-кодов 2FA в криптоприложении — риск безвозвратной потери доступа. Генерируем 8-10 одноразовых кодов при активации 2FA. Backend хранит их как bcrypt-хэши. Мобильный показывает их один раз с возможностью скопировать или скачать как текстовый файл.
Реализация backup-кодов требует отдельной ветки в flow логина: если поле ввода TOTP — дать возможность переключиться на "Использовать резервный код". После использования — код инвалидируется, пользователь получает предупреждение о количестве оставшихся.
| Метод хранения | Доступность | Безопасность |
|---|---|---|
| Бумажный носитель | Высокая | Низкая (утрата) |
| Password manager | Высокая | Высокая |
| Скриншот на устройстве | Средняя | Средняя |
Подробнее о защите экрана ввода кода
На Android используется `FLAG_SECURE` для блокировки скриншотов. На iOS скрывается содержимое при переключении приложений через `applicationWillResignActive`. Поле ввода кода должно иметь `isSecureTextEntry = true`, чтобы избежать автозаполнения и утечки через сторонние клавиатуры.Что входит в работу
- Backend: верификация TOTP, генерация QR-URI, хранение backup-кодов (bcrypt) и секретов (зашифровано), API для настройки и сброса 2FA.
- Mobile: экран ввода TOTP, onboarding с QR, защита от скриншотов, индикация backup-кодов.
- Документация: описание flow, схема защиты, инструкция для пользователя.
- CI/CD: автоматическая подпись приложения (code signing) и распространение через TestFlight / Firebase App Distribution.
- Поддержка: 2 недели после запуска, исправление багов.
Стоимость одного взлома для криптокомпании может достигать $100 000, поэтому инвестиции в 2FA оправданы. Экономия от внедрения TOTP по сравнению с SMS составляет около $15 000 в год на каждые 10 000 пользователей.
Сроки и стоимость
Интеграция TOTP 2FA (настройка, flow входа, backup-коды, защита экрана) — 1-2 недели. Стоимость рассчитывается индивидуально, зависит от текущей архитектуры и необходимости доработок backend. Мы оценили 15+ проектов с криптовалютной тематикой — пишите, обсудим ваш случай.
Мы — команда мобильных разработчиков с многолетним опытом. Реализовали 2FA для десятка криптобирж и кошельков. Гарантируем соответствие App Store Review Guidelines (Section 4.2/5.1) и Google Play политикам. Свяжитесь с нами, чтобы получить консультацию и технический аудит текущей системы логина. Закажите внедрение TOTP сегодня — защитите активы пользователей от SIM-swap атак.







