Разработка мобильного приложения для хранения документов (Digital Wallet)
Паспорт в телефоне — звучит просто, пока не сталкиваешься с тем, что у пользователя iOS 15, устройство без Face ID, а документ нужно предъявить офлайн с криптографическим подтверждением подлинности. Именно здесь стандартный «файловый менеджер с красивым UI» превращается в провальный продукт, а правильный Digital Wallet — в отдельный инжиниринговый проект.
Главная инженерная проблема: где и как хранить
Большинство первых версий таких приложений делают одно и то же: сохраняют PDF в Documents/ и шифруют AES-256. Этого катастрофически мало. Проблема не в алгоритме шифрования — проблема в управлении ключами.
Если ключ хранится рядом с данными (даже обёрнутый в SecKeyCreateRandomKey), при джейлбрейке или физическом доступе к устройству данные восстанавливаются. Правильная схема: мастер-ключ создаётся в Secure Enclave на iOS (kSecAttrTokenIDSecureEnclave), он никогда не покидает чип. На Android аналог — Android Keystore с StrongBox на устройствах с выделенным HSM (Pixel 3+, Samsung с Knox). Документ шифруется производным ключом через HKDF, производный ключ — мастер-ключом. Без биометрии или PIN — ключ недоступен.
Второй болевой момент — резервные копии. По умолчанию Documents/ на iOS попадает в iCloud Backup. Документы пользователя улетают в облако без ведома разработчика. Спасает isExcludedFromBackup = true для директории хранилища и явный атрибут NSURLIsExcludedFromBackupKey.
Верификация подлинности документов при импорте
Хранить — полдела. Пользователи ожидают, что приложение умеет хотя бы базово проверить документ при загрузке: не повреждён ли PDF, совпадает ли MRZ в паспорте с визуальным содержимым, не просрочен ли документ.
Для MRZ-парсинга используем Vision framework на iOS (VNRecognizeTextRequest) или ML Kit Document Scanner на Android. OCR зоны MRZ даёт точность >98% на качественной фотографии. Для PDF — PDFKit на iOS, PdfRenderer на Android: проверяем цифровую подпись документа (PDFDocument.accessPermissions, X.509 chain в embedded CMS).
Полная цепочка верификации eIDAS/PAdES — отдельная тема, но базовый чек встроить реально за 3-4 дня.
Структура хранилища
WalletVault/
├── index.encrypted # CBOR-манифест всех документов (ID, тип, дата, thumbnail hash)
├── docs/
│ ├── {uuid}.enc # Зашифрованный документ (AES-GCM, 256-bit)
│ └── {uuid}.meta.enc # Метаданные (имя, теги, срок действия)
└── keys/
└── vault.key.ref # Ссылка на ключ в Keychain/Keystore (не сам ключ)
Манифест-индекс позволяет отображать список документов без расшифровки самих файлов — thumbnails хранятся отдельно, пережаты до 64×64 px.
Офлайн-предъявление и верификация другой стороной
Сценарий «показать документ инспектору» требует больше, чем просто показать картинку. Для серьёзных кейсов (транспортное удостоверение, корпоративный бейдж) реализуем ISO 18013-5 (mDL — mobile Driving Licence) поверх BLE/NFC: верификатор запрашивает конкретные поля (только имя и дата рождения, без адреса), устройство отвечает подписанным CBOR-объектом. Пользователь видит, какие поля раскрываются — selective disclosure в действии.
Для менее критичных сценариев достаточно QR с подписанным JWT + короткий срок жизни (TTL 60 секунд).
Этапы работы
Аудит требований к типам документов и сценариям предъявления → проектирование схемы хранения и управления ключами → разработка Vault-модуля → интеграция OCR/MRZ-верификации → UI для управления документами → security review → публикация.
Одна платформа с базовым хранилищем: от 5 недель. Две платформы с MRZ, офлайн-верификацией по ISO 18013-5 и MDM-интеграцией: 3–5 месяцев. Стоимость рассчитывается индивидуально после анализа требований.







