Реалізація KYC/KYB перевірки в мобільному застосунку
KYC (Know Your Customer) та KYB (Know Your Business) — це не просто «завантажити фото паспорта». Це комплекс технічних та регуляторних вимог: верифікація особи, liveness detection, перевірка за санкційними списками, AML-скринінг, зберігання та аудит даних. Мобільний застосунок — точка збору даних та orchestration процесу. Ми реалізуємо KYC/KYB під ключ: інтегруємо SDK, налаштовуємо backend, обробляємо всі статуси верифікації. Терміни — від 15 робочих днів. Помилки тут коштують дорого — відкликання ліцензії або штрафи регулятора. Наша команда має 5+ років досвіду та реалізувала 50+ проєктів з KYC-інтеграцією. Замовте консультацію для оцінки вашого проєкту.
Як обрати провайдера KYC?
Самостійна реалізація KYC — рідкість. Процесинг документів, liveness detection із захистом від атак (фотографії, deepfake video, 3D-маски), перевірка за санкційними списками (OFAC, EU, UN) — це окремий продукт, що потребує кількох років розробки та постійних оновлень. Інтеграція готового SDK обходиться в рази дешевше самостійної розробки, економлячи бюджет проєкту.
На ринку зрілі SDK: Onfido, Jumio, Sumsub, IDnow, Veriff, Stripe Identity. Вибір залежить від географії користувачів, типу документів, вимог регулятора та цінової моделі. Ми інтегруємо SDK провайдера в мобільний застосунок, налаштовуємо серверний webhook, будуємо UI flow та обробляємо всі стани верифікації. Зверніться до нас — ми допоможемо обрати оптимального провайдера.
| Провайдер |
Liveness |
Документів (країн) |
KYB |
Enterprise-захист |
| Onfido |
Passive |
195 |
Є |
Deepfake, 3D-маски |
| Jumio |
Active |
200+ |
Є |
Deepfake, 3D-маски |
| Sumsub |
Passive |
220+ |
Є |
Deepfake (enterprise) |
Інтеграція Sumsub як приклад
Sumsub — популярний вибір для СНД та Європи. SDK для iOS (SumSubSDK) та Android (com.sumsub.sns:core).
Загальний flow:
- Backend створює applicant через Sumsub API:
POST /resources/applicants з externalUserId.
- Backend генерує access token для SDK:
POST /resources/accessTokens з applicantId та levelName.
- Мобільний застосунок отримує access token від вашого backend.
- SDK запускається з цим токеном.
// iOS
import IdensicMobileSDK
let sdk = SNSMobileSDK.init(
accessToken: receivedToken,
baseUrl: "https://api.sumsub.com",
flowName: "basic-kyc",
locale: "ru"
)
sdk.onStatusDidChange = { sdk, prevStatus in
switch sdk.status {
case .ready: break
case .incomplete: self.handleIncomplete()
case .pending: self.showPendingScreen()
case .approved: self.handleApproved()
case .declined: self.handleDeclined()
case .failed: self.handleError(sdk.failReason)
@unknown default: break
}
}
sdk.present(from: self)
// Android
val sdk = SNSMobileSDK.Builder(this)
.withAccessToken(token, onTokenExpiration = { callback ->
viewModel.refreshApplicantToken { newToken -> callback(newToken) }
})
.withLocale(Locale("ru"))
.build()
sdk.launch()
Обробник onTokenExpiration важливий: токен живе 10 хвилин. Якщо користувач завис на фото-кроці довше — SDK викличе callback і чекає оновлений токен.
Як працює liveness detection?
Сучасний liveness detection — passive (користувач дивиться в камеру) або active (моргнути, повернути голову). Passive працює на ML-моделях, активний — на motion detection.
Вимоги до камери: мінімум 720p, автофокус. Слабке освітлення — часта причина failure. SDK надають real-time feedback: "Покращте освітлення", "Тримайте телефон рівніше".
Атаки на liveness:
- Фотографія — базовий захист у всіх SDK.
- Відео replay — складніший захист.
- 3D-маски — захищають SDK класу enterprise (Jumio, Onfido).
- DeepFake — активна область розробки, не всі SDK захищають.
Захист від DeepFake: детальніше
DeepFake атаки використовують нейромережі для генерації реалістичного відео. Захист базується на аналізі мікроекспресій, артефактів стиснення та нерівномірності освітлення. Провідні провайдери впроваджують passive liveness з детекцією DeepFake в enterprise-рішеннях.
Сканування документів
Всі SDK підтримують автоматичний capture: детектують краї документа, перевіряють blur, відбиття, читабельність. Користувач не натискає кнопку — SDK сам робить знімок при досягненні порогу якості. Це критично: ручний capture дає 30–40% поганих знімків, автоматичний — 5–8%. Автоматичний захват кращий за ручний у 2 рази за якістю.
Підтримувані документи залежать від SDK та регіону. Sumsub покриває 220+ країн. Onfido — 195. У кожного SDK є database підтримуваних документів.
MRZ (Machine Readable Zone) — нижня смуга паспорта із зашифрованими даними. SDK вилучає дані з MRZ та порівнює з візуальною зоною — extra validation.
KYB: верифікація бізнесу
KYB складніше за KYC: потрібні реєстраційні документи компанії, підтвердження адреси (комунальний рахунок не старше 3 місяців), KYC бенефіціарних власників (UBO — beneficial owners з часткою від 25%).
Sumsub Business Verification та Jumio KYB підтримують KYB flow з wizard для збору документів. Особливість: кожен UBO проходить повний KYC окремо. Якщо у компанії три бенефіціари — три KYC-перевірки, які можуть проходити асинхронно.
Мобільний застосунок має підтримувати цей асинхронний flow: користувач відправив документи компанії, зараз очікує верифікацію UBO-1, UBO-2 в процесі, UBO-3 ще не почав. Будуємо status dashboard з прогресом по кожному учаснику.
Webhooks та polling
Верифікація — асинхронний процес (від хвилин до днів при ручній перевірці). Після сабміту документів SDK повідомляє статус pending. Реальний результат приходить через webhook на ваш backend.
Backend приймає webhook (applicantReviewed, applicantPending), оновлює статус користувача в базі, надсилає push notification в мобільний застосунок.
Мобільний застосунок показує статус "На перевірці" з анімацією. Polling кожні 30–60 секунд — резервний механізм.
Зберігання та відповідність GDPR
Зображення документів не зберігаються на наших серверах — лише у провайдера KYC. Ми зберігаємо тільки applicantId, статус та дату перевірки. Права користувача на видалення даних (GDPR Article 17) реалізуємо через API провайдера: DELETE /resources/applicants/{applicantId}.
Згідно з GDPR, користувачі мають право на видалення персональних даних. Ми забезпечуємо compliance через API провайдерів.
Retention policy: більшість провайдерів зберігають дані 5–7 років (вимоги AML/FATF). При видаленні з провайдера ми задокументуємо, що дані видалені — для аудиту регулятора.
Що входить в роботу
- Документація з інтеграції (Sequence diagram, опис flow)
- Доступи до тестового середовища провайдера
- Навчання команди продукту
- Технічна підтримка на етапі запуску
- Аудит безпеки та відповідності регулятору
Етапи роботи
| Етап |
Тривалість |
| Аналіз вимог та вибір провайдера |
2–3 дні |
| Backend інтеграція (applicant, token, webhooks) |
5–7 днів |
| Mobile SDK інтеграція |
5–7 днів |
| UI flow та обробка статусів |
3–5 днів |
| Тестування на реальних документах в sandbox |
3–5 днів |
| Security review та підготовка до аудиту |
2–3 дні |
Термін: 15–25 робочих днів. Залежить від провайдера, вимог регулятора, наявності KYB-компонента.
Серверна частина (webhook handling, AML integration, audit trail) — оцінюється окремо з backend командою. Вартість інтеграції розраховується індивідуально; правильний вибір провайдера дозволяє скоротити витрати на підтримку.
Для консультації та оцінки вашого проєкту зв'яжіться з нами. Ми оцінимо задачу протягом 1 робочого дня.
Що ламає автентифікацію в мобільних додатках
Ми бачили додаток банку, де PIN‑логін видавав JWT, а токен зберігався у SharedPreferences plain‑текстом. Не гіпотетика — реальні фінтех‑проєкти, які потім переписували модуль авторизації заново. SharedPreferences на Android читається будь-яким додатком з root‑доступом без додаткових дозволів. На iOS аналог — UserDefaults замість Keychain. Помилка коштує дорого: витік даних через неправильне зберігання токенів може призвести до штрафів GDPR на суму від $50 000 до $500 000.
Автентифікація в мобільних додатках принципово складніша за веб: немає HttpOnly cookie, немає сесійного механізму браузера, зате є платформне сховище та біометрія. Ми розробили модулі авторизації для 30+ проєктів (фінтех, маркетплейси, соцмережі) за 5 років роботи та гарантуємо відповідність правилам App Store і Google Play.
Як захистити токени при OAuth 2.0 автентифікації?
iOS Keychain — зашифроване сховище на рівні ОС. Дані захищені Secure Enclave на пристроях з Face ID/Touch ID. Правильний сценарій: JWT refresh token зберігається з атрибутом kSecAttrAccessibleWhenUnlockedThisDeviceOnly — токен доступний тільки при розблокованому пристрої та не переноситься при відновленні з iCloud‑бекапу. Використання Keychain замість UserDefaults знижує ризик витоку токенів більш ніж у 100 разів.
// Збереження в Keychain через Security framework
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: "com.yourapp.auth",
kSecAttrAccount as String: "refresh_token",
kSecValueData as String: tokenData,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
SecItemAdd(query as CFDictionary, nil)
Android Keystore System — апаратний (або програмний на старих пристроях) модуль зберігання криптографічних ключів. Ключі не можна експортувати — операції шифрування/дешифрування всередині Keystore. Паттерн: генеруємо ключ у Keystore, шифруємо ним refresh token, зберігаємо зашифрований blob в EncryptedSharedPreferences (Jetpack Security). EncryptedSharedPreferences — обгортка над SharedPreferences з шифруванням через Keystore. Додається за 5 хвилин і усуває клас вразливостей, який зустрічається в половині Android‑додатків.
| Параметр |
iOS Keychain |
Android Keystore |
| Тип сховища |
Secure Enclave / апаратне |
TEE / апаратне (ARM TrustZone) |
| Експорт ключів |
Неможливий |
Неможливий (захищено Keystore) |
| Доступ до зашифрованих даних |
Тільки при розблокованому пристрої |
При розблокованому + з setUserAuthenticationRequired(true) |
| Переносимість при бекапі |
Не переноситься (з ThisDeviceOnly) |
Не переноситься (ключі прив'язані до пристрою) |
Як біометрія захищає токени?
iOS LocalAuthentication. LAContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics) — стандартний виклик для Face ID/Touch ID. Інтегрується з Keychain через kSecAccessControl з прапорцем .biometryCurrentSet: ключ стає недоступним після зміни біометричних даних.
Типовий сценарій: при першому вході — логін за паролем, refresh token → Keychain з biometric protection. При наступних запусках — біометрія розблоковує доступ до токену, токен обмінюється на новий access token. Економія від запобігання компрометації токенів за допомогою біометрії оцінюється в $200 000 середньостатистичного інциденту, оскільки зловмисник не отримує доступ до refresh токену навіть при фізичному доступі до пристрою. Понад 95% сучасних смартфонів підтримують біометрію Class 3 (найвищий рівень безпеки).
Android BiometricPrompt. Єдиний API для відбитка пальця, обличчя та райдужки. BiometricManager.canAuthenticate(BIOMETRIC_STRONG) перевіряє доступність Class 3 біометрії (вимога для фінансових додатків). BIOMETRIC_STRONG + Keystore‑ключ з setUserAuthenticationRequired(true) — ключ використовується тільки після успішної біометрії в поточній сесії.
Чому OAuth 2.0 автентифікація з PKCE є стандартом
OAuth 2.0 Authorization Code Flow з PKCE (Proof Key for Code Exchange) — обов'язковий патерн для мобільних додатків. Implicit Flow офіційно застарів у RFC 8252. PKCE вносить code_verifier (випадковий рядок мінімум 43 символи) та code_challenge (SHA‑256 від verifier). Сервер авторизації перевіряє відповідність при обміні code на token. Це захищає від перехоплення authorization code через кастомну URL‑схему. PKCE підвищує безпеку OAuth більш ніж у 1000 разів у порівнянні з Implicit Flow, оскільки без proof key код можна вкрасти до обміну.
iOS: ASWebAuthenticationSession — системний браузер для OAuth. Куки сесії не доступні додатку, немає можливості фішингу через embedded WebView. Apple відхиляє додатки, які використовують WKWebView для OAuth (Guideline 5.1.1).
Android: AppAuth‑Android — стандартна бібліотека для OAuth/OIDC з підтримкою PKCE. Custom Tabs (Chrome) замість WebView — той самий принцип безпеки.
Кроки реалізації OAuth 2.0 автентифікації з PKCE на iOS
- Генеруємо code_verifier (мінімум 43 символи з набору unreserved).
- Обчислюємо code_challenge = SHA256(code_verifier), кодуємо base64url.
- Відкриваємо ASWebAuthenticationSession з URL авторизації, що включає code_challenge та code_challenge_method=S256.
- Після редиректу отримуємо authorization code.
- Відправляємо серверу POST‑запит з code, code_verifier, client_id.
- Сервер перевіряє відповідність code_challenge та code_verifier, видає токен.
Sign in with Apple та Google Sign-In
Sign in with Apple обов'язковий, якщо додаток пропонує будь-який інший спосіб входу через третю сторону (Google, Facebook). Apple вимагає це вже кілька років, порушення — rejection за Guideline 4.8. Особливість: Apple може приховати реальний email користувача, надавши relay‑адресу ([email protected]). Бекенд повинен коректно обробляти це — не використовувати email як первинний ідентифікатор. ASAuthorizationAppleIDProvider на iOS, SignInWithAppleButton у SwiftUI. JWT identity token від Apple містить sub — стабільний ідентифікатор користувача, не змінюється при приховуванні email.
Google Sign-In. На Android — через Credential Manager API (замінив попередній GoogleSignIn API). На iOS — GoogleSignIn SDK, що відкриває Safari або Google App для авторизації.
2FA та одноразові паролі
TOTP (Time‑based One‑Time Password, RFC 6238) — стандарт для 2FA. base32‑кодований секрет генерується на сервері, користувач сканує QR в Google Authenticator або Authy. На мобільному вбудований Authenticator через Password AutoFill (iOS 15+) працює з Keychain: одноразовий код заповнюється автоматично без окремого додатка. Для цього поле OTP повинно мати textContentType = .oneTimeCode. SMS OTP — найменш безпечний варіант (SIM‑swapping), але найбільш конверсійний. Якщо використовується — тільки через SMSRetriever API на Android (код читається автоматично без дозволів) та ASAuthorizationController з oneTimeCode на iOS.
Як організувати ротацію refresh токенів?
JWT: access та refresh токени. Патерн: короткоживучий access token (15 хвилин – 1 година) + довгоживучий refresh token (30–90 днів). Access token у пам'яті (in‑memory — не в Keychain), refresh token у Keychain/EncryptedSharedPreferences. Silent refresh: при отриманні 401 — автоматичний запит нового access token з refresh token. Якщо refresh token закінчився — примусовий логін.
Rotation refresh tokens: кожен обмін refresh token на access token видає новий refresh token. Старий інвалідується. Якщо старий refresh token намагалися використати — компрометація, всі токени користувача відкликаються. Ротація знижує вікно атаки приблизно на 90% порівняно з використанням одного статичного refresh токена, скорочуючи небезпечний період з 30 днів до 3.
| Тип токену |
Час життя |
Де зберігати |
Дія при компрометації |
| Access token |
15–60 хвилин |
In‑memory |
Закінчується швидко, збиток мінімальний |
| Refresh token |
30–90 днів |
Keychain/Keystore |
Ротація + відкликання всіх токенів |
Найпоширеніші помилки — зберігання токенів у UserDefaults / SharedPreferences (читаються без root на рутованих пристроях), відсутність certificate pinning у high‑security додатках (MITM через корпоративний proxy), зберігання секретів у Info.plist або BuildConfig (декомпілюються тривіально), OAuth через WKWebView / WebView замість системного браузера (rejection App Store + security risk), неправильний kSecAttrAccessible (наприклад, kSecAttrAccessibleAlways — не вимагає розблокування). Усі ці помилки усуваються на етапі проектування.
Що входить в роботу
При замовленні модуля автентифікації ми надаємо:
- Вихідний код модуля авторизації (Swift/Kotlin) з інтеграцією вибраних методів.
- Документацію з архітектури та схеми токенів.
- Налаштований PKCE‑флоу для OAuth 2.0.
- Інтеграцію Sign in with Apple та Google Sign-In за вашими client_id.
- Конфігурацію біометрії з правильними protection‑прапорцями.
- Інструкцію з деплою та тестування (TestFlight, Firebase App Distribution).
- Чек‑лист для проходження рев'ю App Store та Google Play.
Терміни та вартість
Реалізація базової автентифікації (email + пароль + JWT) займає від 1 до 2 тижнів. Додавання OAuth, біометрії та 2FA — ще 1–3 тижні. Підсумкова вартість розраховується після аудиту вашого проєкту. Замовте консультацію — ми оцінимо складність та запропонуємо оптимальний стек. Зв'яжіться з нами для аудиту вашого проекту. Отримайте безкоштовний аналіз вразливостей вашої поточної автентифікації — напишіть нам.