secure_biometric_auth 0.0.1
secure_biometric_auth: ^0.0.1 copied to clipboard
Biometric that used for challenge sign-in support
secure_biometric_auth #
A Flutter plugin for secure biometric authentication with key-pair generation and challenge-based verification. Supports both registering device biometric credentials and authenticating with them, with detailed error handling.
| Android | iOS | |
|---|---|---|
| Support | SDK 21+ | 15.0+ |
This plugin has not been fully tested on iOS devices. Please feel free to open an issue or submit a pull request if you encounter any bugs.
Features #
- Uses StrongBox on compatible Android devices and Secure Enclave on iOS to store cryptographic keys securely.
- Cryptography:
- Android: ECC primary, fallback to RSA (SHA256withRSA/PSS) if ECC generation fails
- iOS: Only ECC (SHA256withECDSA)
- Customizable UI components for signature prompts
- High-level abstractions for managing biometric signatures
- Detailed Error Handling.
Installation #
Add the dependency in your pubspec.yaml:
dependencies:
secure_biometric:
path: ../ # if using local plugin
Then run:
flutter pub get
Usage #
Android Integration #
Activity Changes
This plugin requires the use of a FragmentActivity as opposed to Activity. This can be easily done by switching to use FlutterFragmentActivity as opposed to FlutterActivity in your manifest or your own Activity class if you are extending the base class.
The MainActivity file is usually located in the android/app/src/main/kotlin folder if you are using Kotlin, or in the android/app/src/main/java folder if you are using Java.
For example:
package com.example.myapp
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity : FlutterFragmentActivity()
Permissions
Update your project's AndroidManifest.xml file to include the USE_BIOMETRIC permission.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.app">
// Add USE_BIOMETRIC permision
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
</manifest>
iOS Integration #
Add this in to your Info.plist file.
<key>NSFaceIDUsageDescription</key>
<string>This app is using FaceID for authentication</string>
Import the plugin #
import 'package:secure_biometric_auth/secure_biometric_auth.dart';
Check if device supports biometric #
bool isSupported = await SecureBiometricAuth.isDeviceSupport();
Checks whether the device supports biometric authentication. Returns
trueif supported,falseotherwise.
Check if biometric is already registered #
bool isRegistered = await SecureBiometricAuth.isRegistered();
Checks if the user has already registered biometric credentials.
Useful to determine whether to proceed with registration or directly authenticate.
Register biometric credentials #
final challenge = "server-generated-challenge-string";
final authMessage = AuthMessage(
title: "Register Biometric",
subtitle: "Use your fingerprint or face",
description: "Secure registration of biometric keys",
);
try {
final registerResult = await SecureBiometricAuth.register(
challenge: challenge,
authMessage: authMessage,
);
final publicKey = registerResult.publicKey;
final signature = registerResult.signature;
} on SecureBiometricAuthException catch (e) {
print('Error: ${e.type}, ${e.message}');
}
Registers a new biometric credential using a server-provided challenge. Returns a
publicKeyand asignaturethat should be sent to the backend for verification. Always wrap intry/catchto handleSecureBiometricException.
Authenticate #
final challenge = "server-generated-challenge-string";
final authMessage = AuthMessage(
title: "Authenticate",
subtitle: "Use your fingerprint or face",
description: "Authenticate securely",
);
try {
final result = await SecureBiometricAuth.authenticate(
challenge: challenge,
authMessage: authMessage,
);
final signature = result.signature;
} on SecureBiometricAuthException catch (e) {
print('Error: ${e.type}, ${e.message}');
}
Verifies the user using previously registered biometric credentials.
Signs the server challenge using the securely stored private key. Send the returnedsignatureto the backend for validation.
Remove local biometric credentials #
bool removed = await SecureBiometricAuth.removeAuthenticate();
Deletes the locally stored biometric key pair.. Useful for logout scenarios or resetting biometric authentication.
Cryptography Notes #
Android:
- Primary key: ECC (SHA256withECDSA).
- Fallback key: RSA (SHA256withRSA/PSS) if ECC generation fails on older devices.
- Keys stored in StrongBox when available (hardware-backed keystore).
iOS:
- Only ECC (SHA256withECDSA).
- Keys stored in Secure Enclave (hardware-backed).
Backend considerations:
- Backend must verify signatures using the correct algorithm based on the key type.
- Public key and signature formats differ for ECC and RSA.
Error Handling #
SecureBiometricAuthException is thrown for various errors, with types:
| Type | Description |
|---|---|
deviceNotSupported |
Device does not support biometric |
invalidArguments |
Method called with invalid arguments |
privateKeyIsNotExist |
Private key not found on device |
userCancel |
User canceled authentication |
cancel |
Authentication canceled (system or plugin) |
biometricAuthFailed |
Biometric authentication process failed (fallback default) |
biometricInvalidCredential |
User credential did not match (fingerprint/face failed) |
biometricNoneEnrolled |
No biometric enrolled on device |
biometricLockout |
Biometric locked due to too many failed attempts |
unknown |
Unknown or unexpected error (any step) |