Реализация электронной подписи в мобильном приложении

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Реализация электронной подписи в мобильном приложении
Сложная
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1054
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Реализация электронной подписи в мобильном приложении

Электронная подпись в мобильном приложении — это не картинка с подписью поверх документа. Это криптографическая операция: документ подписывается приватным ключом пользователя, верификатор проверяет подпись публичным ключом и гарантирует, что документ не изменился после подписания и что подписал именно этот пользователь.

В зависимости от юрисдикции и требований различают квалифицированную (КЭП — с токеном и сертификатом от аккредитованного УЦ), усиленную неквалифицированную (НЭП — своя PKI) и простую электронную подпись (ПЭП — логин/пароль, SMS-код). Для большинства коммерческих кейсов достаточно НЭП; КЭП нужна для госуслуг и юридически значимого документооборота с госорганами.

PKI на мобильном устройстве

Самый распространённый подход для НЭП: приватный ключ генерируется на устройстве и хранится в Keychain (iOS) или Android Keystore. Публичный ключ регистрируется на сервере. Подписание происходит на устройстве — приватный ключ никогда не покидает Secure Enclave/TEE.

Генерация ключевой пары на Android:

val keyPairGenerator = KeyPairGenerator.getInstance(
    KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore"
)
keyPairGenerator.initialize(
    KeyPairGeneratorSpec.Builder(context)
        .setAlias("user_signing_key")
        .setKeyType("EC")
        .setKeySize(256)
        .setSubject(X500Principal("CN=User"))
        .setSerialNumber(BigInteger.ONE)
        .setStartDate(startDate)
        .setEndDate(endDate)
        .build()
)
val keyPair = keyPairGenerator.generateKeyPair()
// публичный ключ регистрируем на сервере
val publicKeyBase64 = Base64.encode(keyPair.public.encoded)

Для подписания документа:

val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
val privateKey = keyStore.getKey("user_signing_key", null) as PrivateKey

val signature = Signature.getInstance("SHA256withECDSA")
signature.initSign(privateKey)
signature.update(documentBytes)
val signatureBytes = signature.sign()

iOS, Swift:

let attributes: [String: Any] = [
    kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
    kSecAttrKeySizeInBits as String: 256,
    kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave,
    kSecPrivateKeyAttrs as String: [
        kSecAttrIsPermanent as String: true,
        kSecAttrApplicationTag as String: "com.example.signing".data(using: .utf8)!
    ]
]
var error: Unmanaged<CFError>?
guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
    // обработать ошибку
}
let publicKey = SecKeyCopyPublicKey(privateKey)!

kSecAttrTokenIDSecureEnclave — ключ создаётся внутри Secure Enclave и не может быть извлечён даже при компрометации основного процессора.

Подписание с биометрической аутентификацией

Для юридически значимых операций ключ подписания должен быть защищён подтверждением личности. Привязка к биометрии через Keystore/Keychain: ключ доступен только после успешной биометрической аутентификации в рамках текущей сессии.

Android:

keyGenParameterSpec = KeyGenParameterSpec.Builder(...)
    .setUserAuthenticationRequired(true)
    .setUserAuthenticationParameters(0, KeyProperties.AUTH_BIOMETRIC_STRONG)
    .build()

При каждом подписании:

val biometricPrompt = BiometricPrompt(activity, executor, callback)
val promptInfo = BiometricPrompt.PromptInfo.Builder()
    .setTitle("Подпишите документ")
    .setSubtitle("Используйте биометрию для подтверждения")
    .setNegativeButtonText("Отмена")
    .build()

// привязываем CryptoObject с нашим Signature объектом
biometricPrompt.authenticate(promptInfo, BiometricPrompt.CryptoObject(signature))

В onAuthenticationSucceeded callback получаем result.cryptoObject?.signature — разблокированный объект подписи, готовый к работе.

Формат подписи и верификация на сервере

Для стандартизации используем CMS (Cryptographic Message Syntax, RFC 5652) или JWS (JSON Web Signature, RFC 7515). JWS удобнее для REST API:

Header.Payload.Signature

Header: {"alg": "ES256", "kid": "user_key_id"} Payload: base64url-encoded документ или его хэш Signature: ES256 подпись

На сервере верификация через любую JWT библиотеку с ES256 поддержкой. Python: PyJWT, cryptography. Node.js: jose, jsonwebtoken. Java: nimbus-jose-jwt.

Долгосрочная валидность и timestamp

Если документ должен оставаться валидным годами (после истечения сертификата подписанта), используем RFC 3161 Trusted Timestamping. Timestamp Authority (TSA) подписывает хэш документа + время своим ключом. Даже если ключ пользователя позже скомпрометирован, timestamp доказывает, что подпись была создана в определённый момент времени.

Публичные TSA: Freetsa.org, DigiCert TSA. Интеграция: bouncycastle на Android, Security.framework + RFC 3161 запрос на iOS.

Варианты интеграции с внешними КЭП-провайдерами

Для квалифицированной подписи в России — КриптоПро, Рутокен, ViPNet. У каждого есть мобильные SDK. Интеграция через CryptoPro CSP SDK для Android/iOS: подписание на стороне токена (физического или программного), приложение только передаёт данные SDK.

Для международных кейсов — DocuSign SDK, Adobe Sign API, HelloSign. Они абстрагируют криптографию, но привязывают к конкретному провайдеру.

Сроки реализации НЭП с генерацией ключей в Keystore/Keychain, биометрическим подтверждением и серверной верификацией — 3–5 дней. Интеграция с КЭП-провайдером или внешним документооборотным сервисом — индивидуальная оценка после анализа API провайдера.