Electronic Signature Implementation in Mobile App

TRUETECH is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Electronic Signature Implementation in Mobile App
Complex
~3-5 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Electronic Signature Implementation in Mobile Applications

Electronic signature in a mobile app is not a picture overlaid on a document. It's a cryptographic operation: the document is signed with the user's private key, and the verifier checks the signature using the public key, guaranteeing that the document hasn't changed since signing and that this specific user signed it.

Depending on jurisdiction and requirements, there are qualified e-signature (QES — with token and certificate from accredited CA), advanced electronic signature (AES — own PKI), and simple electronic signature (SES — login/password, SMS code). For most commercial use cases, AES is sufficient; QES is needed for government services and legally significant document workflows with authorities.

PKI on a Mobile Device

The most common approach for AES: the private key is generated on the device and stored in Keychain (iOS) or Android Keystore. The public key is registered on the server. Signing happens on the device — the private key never leaves Secure Enclave/TEE.

Generating a Key Pair on 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()
// register public key on server
val publicKeyBase64 = Base64.encode(keyPair.public.encoded)

To sign a document:

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 {
    // handle error
}
let publicKey = SecKeyCopyPublicKey(privateKey)!

kSecAttrTokenIDSecureEnclave — the key is created inside Secure Enclave and cannot be extracted even if the main processor is compromised.

Signing with Biometric Authentication

For legally significant operations, the signing key must be protected by identity confirmation. Bind to biometrics via Keystore/Keychain: key accessible only after successful biometric authentication within the current session.

Android:

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

On each signing:

val biometricPrompt = BiometricPrompt(activity, executor, callback)
val promptInfo = BiometricPrompt.PromptInfo.Builder()
    .setTitle("Sign Document")
    .setSubtitle("Use biometry to confirm")
    .setNegativeButtonText("Cancel")
    .build()

// bind CryptoObject with our Signature object
biometricPrompt.authenticate(promptInfo, BiometricPrompt.CryptoObject(signature))

In onAuthenticationSucceeded callback, we get result.cryptoObject?.signature — an unlocked signature object ready to use.

Signature Format and Server Verification

For standardization, use CMS (Cryptographic Message Syntax, RFC 5652) or JWS (JSON Web Signature, RFC 7515). JWS is more convenient for REST API:

Header.Payload.Signature

Header: {"alg": "ES256", "kid": "user_key_id"} Payload: base64url-encoded document or its hash Signature: ES256 signature

On the server, verify through any JWT library with ES256 support. Python: PyJWT, cryptography. Node.js: jose, jsonwebtoken. Java: nimbus-jose-jwt.

Long-Term Validity and Timestamp

If a document must remain valid for years (after the signer's certificate expires), use RFC 3161 Trusted Timestamping. Timestamp Authority (TSA) signs the document hash + time with its own key. Even if the user's key is later compromised, the timestamp proves when the signature was created.

Public TSAs: Freetsa.org, DigiCert TSA. Integration: bouncycastle on Android, Security.framework + RFC 3161 request on iOS.

Integration Options with External QES Providers

For qualified signatures in Russia — CryptoPro, Rutoken, ViPNet. Each has mobile SDKs. Integration via CryptoPro CSP SDK for Android/iOS: signing happens on the token side (physical or software), the app only passes data to the SDK.

For international use cases — DocuSign SDK, Adobe Sign API, HelloSign. They abstract cryptography but tie to specific providers.

Timeline for implementing AES with key generation in Keystore/Keychain, biometric confirmation, and server verification — 3–5 days. Integration with QES provider or external document workflow service — individual assessment after analyzing provider API.