Mobile Development 22 min read

How to Securely Add Fingerprint & Face ID Login to Your iOS App with ECDSA

This article walks through the design, security considerations, and step‑by‑step implementation of fingerprint and face‑recognition login for an iOS driver app, covering biometric enable/disable, server‑side verification, auth‑code replay protection, ECDSA signing, keychain management, and common pitfalls.

Huolala Tech
Huolala Tech
Huolala Tech
How to Securely Add Fingerprint & Face ID Login to Your iOS App with ECDSA

Background

In the Huolala driver app a driver may need to switch accounts across multiple devices; the token may expire and the SMS verification flow can be blocked by carriers. To reduce SMS cost and handle extreme cases, fingerprint/face authentication was introduced.

Exploration

Industry status

Most mainstream apps still rely on system‑provided biometric APIs; only a few, like Alipay, implement custom face recognition. The low adoption suggests many companies are still evaluating security.

Apple’s official security white‑paper confirms the safety of the Secure Enclave‑based biometric data.

Overall solution for Huolala

Local biometric authentication + one‑time auth code + ECDSA local signing & server verification.

Enabling / disabling biometric login

Biometric capability must be bound to the account while the app is already logged in. Users can later disable it, similar to binding/unbinding a third‑party login.

Using biometric login

After enabling, the user can log in quickly via biometric authentication.

Why server‑side verification?

Pure local authentication cannot guarantee data integrity; an attacker could hijack or tamper requests. Server verification ensures the data received is authentic.

Why an auth code?

An auth code (random nonce) prevents replay attacks by making each request unique and optionally time‑limited.

Why signing instead of encryption? Why ECDSA?

Signing validates integrity and source authenticity, while encryption only provides confidentiality. ECDSA (ECC‑based) offers better performance and smaller keys, and keys can be generated and stored in the Secure Enclave, which cannot be exported.

Implementation

Environment

Target iOS version >= 11.3. Add NSFaceIDUsageDescription to Info.plist for the first‑time face‑ID prompt.

Core library LocalAuthentication

Use LAContext to check capability and evaluate policy.

1. Check device capability

BOOL can = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error];

Read context.biometryType after calling canEvaluatePolicy:error:.

2. Perform biometric authentication

[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"Login with biometrics" reply:^(BOOL success, NSError *error) { /* handle result */ }];

Handle success, error codes (e.g., LAErrorUserFallback, LAErrorBiometryLockout).

ECDSA key management

Creating / deleting key pair

CFErrorRef err = NULL;
SecAccessControlRef ac = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, kSecAccessControlPrivateKeyUsage, &err);
NSDictionary *params = @{ (id)kSecAttrTokenID: (id)kSecAttrTokenIDSecureEnclave,
                         (id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom,
                         (id)kSecAttrKeySizeInBits: @(256),
                         (id)kSecAttrLabel: @"MyKeyLabel",
                         (id)kSecAttrApplicationTag: @"MyKeyTag",
                         (id)kSecPrivateKeyAttrs: @{ (id)kSecAttrAccessControl: CFBridgingRelease(ac), (id)kSecAttrIsPermanent: @(YES) } };
SecKeyRef privateKey = SecKeyCreateRandomKey((CFDictionaryRef)params, (void *)&err);
if (privateKey) { /* success */ }

Exporting public key

SecKeyRef pubKey = SecKeyCopyPublicKey(privateKey);
NSDictionary *pubParams = @{ (id)kSecClass: (id)kSecClassKey,
                           (id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom,
                           (id)kSecAttrKeySizeInBits: @(256),
                           (id)kSecAttrLabel: @"MyKeyLabel",
                           (id)kSecAttrApplicationTag: @"MyKeyTag",
                           (id)kSecValueRef: (__bridge id)pubKey,
                           (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPublic,
                           (id)kSecReturnData: @(YES) };
CFTypeRef dataRef = NULL;
OSStatus status = SecItemAdd((CFDictionaryRef)pubParams, &dataRef);
NSData *publicData = (status == errSecSuccess) ? (__bridge_transfer NSData *)dataRef : nil;
// prepend Secp256r1 header if needed and Base64‑encode

Signing data

NSData *toSign = [stringToSign dataUsingEncoding:NSUTF8StringEncoding];
CFDataRef signed = SecKeyCreateSignature(privateKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (CFDataRef)toSign, &err);
NSString *signatureBase64 = [(NSData *)CFBridgingRelease(signed) base64EncodedStringWithOptions:0];

Verifying signature locally

SecKeyRef pubKey = SecKeyCreateWithData((CFDataRef)keyData, (__bridge CFDictionaryRef)attributes, &err);
Boolean ok = SecKeyVerifySignature(pubKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (CFDataRef)originData, (CFDataRef)signedData, &err);

Remote account‑device‑biometric mapping

Maintain a server‑side table linking accounts, devices, biometric types, and stored public keys to support multiple bindings.

Data caching

Cache the random auth code, evaluatedPolicyDomainState, and binding status during the enable flow; clear caches on failure or when disabling.

Pitfalls & fixes

Incorrect caching of latestLoginUserInfo after an app upgrade caused account‑id=0 bindings, leading to “device key limit reached” or “device key verification failed” errors. The fix adds explicit cache refresh before binding and graceful handling when no binding is found (clear cache and report success for unbinding).

Conclusion

The article outlines the end‑to‑end process of integrating fingerprint/face ID login on iOS, including biometric enable/disable, server verification, auth‑code replay protection, ECDSA signing, keychain handling, data caching, and lessons learned from real‑world issues.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

iOSBiometricsKeychainECDSA
Huolala Tech
Written by

Huolala Tech

Technology reshapes logistics

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.