flutter_biometric_crypto 0.1.4 copy "flutter_biometric_crypto: ^0.1.4" to clipboard
flutter_biometric_crypto: ^0.1.4 copied to clipboard

A Flutter package for biometric-protected encryption of small secrets using Android Keystore and iOS Keychain/Secure Enclave.

Flutter Biometric Crypto Logo

flutter_biometric_crypto #

Enterprise-grade biometric-protected encryption for Flutter apps

pub package License: MIT

Protect your app's sensitive data with hardware-backed security. flutter_biometric_crypto provides a simple, secure way to encrypt small secrets (like API keys, tokens, or passwords) using your device's biometric authentication and secure hardware storage.


✨ Why Choose This Package? #

In today's security-conscious world, protecting user data is paramount. This package bridges the gap between convenience and security.

How Flutter Biometric Crypto Works

Key Features #

  • πŸ›‘οΈ Hardware-Backed Security: Your private keys never leave the device's secure hardware (Android Keystore or iOS Secure Enclave).
  • πŸ‘† Seamless User Experience: Users authenticate with their fingerprint or faceβ€”no passwords to remember.
  • πŸ”’ Zero-Knowledge Architecture: Even you as the developer can't access the encrypted data without user authentication.
  • ⚑ Production Ready: Battle-tested with comprehensive error handling and security best practices.

Perfect for storing authentication tokens, API keys, payment credentials, or any sensitive data that needs an extra layer of protection.

πŸš€ Quick Start #

Installation #

Add flutter_biometric_crypto to your pubspec.yaml:

dependencies:
  flutter_biometric_crypto: ^0.1.4

Then run:

flutter pub get

Basic Usage #

import 'package:flutter_biometric_crypto/flutter_biometric_crypto.dart';
import 'dart:typed_data';

// 1. Initialize the key (one-time setup)
await FlutterBiometricCrypto.initKey();

// 2. Check if biometric is available
final isAvailable = await FlutterBiometricCrypto.isBiometricAvailable();
if (!isAvailable) {
  // Handle gracefully - show alternative authentication
  return;
}

// 3. Encrypt your sensitive data
final sensitiveData = Uint8List.fromList('MySecretAPIKey123'.codeUnits);
final encrypted = await FlutterBiometricCrypto.encrypt(sensitiveData);

// 4. Decrypt when needed (prompts for biometric)
final decrypted = await FlutterBiometricCrypto.decrypt(encrypted);
final decryptedText = String.fromCharCodes(decrypted);
print(decryptedText); // Output: MySecretAPIKey123

That's it! Your data is now protected by biometric authentication and secure hardware storage.

πŸ“± Platform Setup #

Android #

  1. Set Minimum SDK Version (API 23+ required)

Add to android/app/build.gradle:

android {
    defaultConfig {
        minSdkVersion 23  // Android 6.0+
    }
}
  1. Add Biometric Dependency (Included automatically, but ensure conflicts don't exist)

The plugin uses androidx.biometric:biometric:1.1.0.

  1. Permissions (automatically included)

The plugin automatically includes required permissions:

  • USE_BIOMETRIC
  • USE_FINGERPRINT

iOS #

  1. Minimum iOS Version: iOS 12.0 or higher

  2. Add Face ID Usage Description

Add to ios/Runner/Info.plist:

<key>NSFaceIDUsageDescription</key>
<string>This app uses Face ID to securely authenticate and decrypt your encrypted data.</string>
  1. Keychain Access (automatic)

The plugin uses iOS Keychain which is available by default. For devices with Secure Enclave, keys are automatically stored there for maximum security.

πŸ’‘ Real-World Examples #

Storing an API Token #

// Encrypt and store API token
final apiToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
final tokenBytes = Uint8List.fromList(apiToken.codeUnits);
final encryptedToken = await FlutterBiometricCrypto.encrypt(tokenBytes);

// Store encryptedToken in your app's secure storage
await secureStorage.write(key: 'api_token', value: base64Encode(encryptedToken));

// Later, retrieve and decrypt
final storedEncrypted = base64Decode(await secureStorage.read(key: 'api_token'));
final decryptedToken = await FlutterBiometricCrypto.decrypt(storedEncrypted);
final token = String.fromCharCodes(decryptedToken);

Protecting User Credentials #

// Encrypt user password before storing
final password = 'userPassword123';
final passwordBytes = Uint8List.fromList(password.codeUnits);
final encryptedPassword = await FlutterBiometricCrypto.encrypt(passwordBytes);

// Store encrypted password
// ... later decrypt when user needs to authenticate

πŸ› οΈ API Reference #

initKey() #

Generates a new RSA 2048 key pair if one doesn't exist. Safe to call multiple timesβ€”it won't create duplicate keys.

await FlutterBiometricCrypto.initKey();

When to call: Once during app initialization or before first use.

encrypt(Uint8List data) #

Encrypts data using the public key. No authentication required.

final encrypted = await FlutterBiometricCrypto.encrypt(data);

Parameters:

  • data: Data to encrypt (max 1 KB / 1024 bytes)

Returns: Future<Uint8List> - Encrypted data

Throws:

  • DataTooLargeException - Data exceeds 1 KB limit
  • KeyNotFoundException - Key not initialized (call initKey() first)
  • EncryptionException - Encryption operation failed

decrypt(Uint8List encrypted) #

Decrypts data using the private key. Requires biometric authentication.

final decrypted = await FlutterBiometricCrypto.decrypt(encrypted);

Parameters:

  • encrypted: Previously encrypted data

Returns: Future<Uint8List> - Decrypted data

Throws:

  • BiometricNotAvailableException - No biometric sensor or not enrolled
  • BiometricAuthenticationFailedException - User failed or cancelled authentication
  • KeyNotFoundException - Key not initialized
  • DecryptionException - Decryption operation failed

isBiometricAvailable() #

Checks if biometric authentication is available and properly configured.

final available = await FlutterBiometricCrypto.isBiometricAvailable();
if (available) {
  // Proceed with biometric-protected operations
}

Returns: Future<bool> - true if biometric is ready to use

deleteKey() #

Permanently removes the key pair from secure storage. Use with caution!

await FlutterBiometricCrypto.deleteKey();

Note: After deletion, you'll need to call initKey() again before encrypting/decrypting.

⚠️ Error Handling #

Always handle exceptions gracefully:

try {
  final encrypted = await FlutterBiometricCrypto.encrypt(data);
  // Success!
} on DataTooLargeException catch (e) {
  // Data is too large - consider splitting or using hybrid encryption
  print('Error: ${e.message}');
} on KeyNotFoundException catch (e) {
  // Initialize key first
  await FlutterBiometricCrypto.initKey();
  // Retry encryption
} on EncryptionException catch (e) {
  // Handle encryption failure
  print('Encryption failed: ${e.message}');
}

try {
  final decrypted = await FlutterBiometricCrypto.decrypt(encrypted);
  // Success!
} on BiometricNotAvailableException catch (e) {
  // No biometric available - show alternative authentication method
  showAlternativeAuth();
} on BiometricAuthenticationFailedException catch (e) {
  // User failed authentication or cancelled
  showError('Authentication failed. Please try again.');
} on DecryptionException catch (e) {
  // Handle decryption failure
  print('Decryption failed: ${e.message}');
}

πŸ”’ Security Best Practices #

  1. Always Check Biometric Availability

    if (!await FlutterBiometricCrypto.isBiometricAvailable()) {
      // Provide fallback authentication method
    }
    
  2. Handle Errors Securely

    • Never log sensitive data or encryption keys
    • Don't expose error details to end users
    • Log errors for debugging but sanitize sensitive information
  3. Key Management

    • Call initKey() during app initialization
    • Only delete keys when user explicitly requests account deletion
    • Never extract or share private keys
  4. Data Size Considerations

    • Maximum 1 KB per encryption operation
    • For larger data, use hybrid encryption:
      • Generate a symmetric key (AES)
      • Encrypt the symmetric key with this package
      • Encrypt your data with the symmetric key

πŸ“Š Limitations & Considerations #

Data Size Limit #

Maximum: 1 KB (1024 bytes) per encryption operation.

Why? RSA encryption is designed for small data. For larger payloads, use hybrid encryption (encrypt a symmetric key with this package, then use AES for your data).

Platform Support #

  • βœ… Android: API 23+ (Android 6.0+)
  • βœ… iOS: 12.0+
  • ❌ Web, macOS, Windows, Linux (not supported)

Biometric Requirements #

  • Android: Requires fingerprint sensor or face unlock
  • iOS: Requires Face ID or Touch ID enrollment
  • Fallback: iOS may fall back to device passcode if biometric fails

Key Persistence #

Keys are stored in platform-specific secure storage:

  • Lost if: App is uninstalled or app data is cleared
  • Persists: Across app updates and device restarts
  • Not synced: Keys are device-specific and never leave the device

πŸ§ͺ Testing #

Unit Tests #

flutter test

Integration Tests #

Requires a real device or emulator with biometric support:

flutter test integration_test/flutter_biometric_crypto_test.dart

Note:

  • Android emulators: Configure fingerprint in Settings > Security
  • iOS simulators: Use Hardware > Face ID > Enrolled

πŸ“± Example App #

A complete example app demonstrating all features is available in the example/ directory.

cd example
flutter run

The example app includes:

  • Key initialization
  • Biometric availability checking
  • Encryption/decryption workflow
  • Error handling examples
  • UI for testing all features

πŸ› Troubleshooting #

"Biometric not available" on Android #

  • βœ… Ensure device has fingerprint sensor or face unlock
  • βœ… Set up biometric authentication in device Settings
  • βœ… Verify minSdkVersion is 23 or higher
  • βœ… Check that androidx.biometric:biometric:1.1.0 is in dependencies

"Biometric not available" on iOS #

  • βœ… Ensure Face ID or Touch ID is set up on device
  • βœ… Verify NSFaceIDUsageDescription is in Info.plist
  • βœ… Check app entitlements in Xcode

"Key not found" error #

  • βœ… Call initKey() before first use
  • βœ… Ensure app has proper permissions
  • βœ… On Android, verify device supports Android Keystore

Decryption fails immediately #

  • βœ… Check isBiometricAvailable() first
  • βœ… Ensure user has enrolled biometrics
  • βœ… Verify key was initialized successfully

πŸ‘¨β€πŸ’» Author #

Godfrey Lebo - Fullstack Developer & Technical PM

With 9+ years of industry experience, I specialize in building AI-powered applications, scalable mobile solutions, and secure backend systems. I've led teams delivering marketplaces, fintech platforms, and AI applications serving thousands of users.

🀝 Contributing #

Contributions are welcome! Whether it's:

  • πŸ› Bug reports
  • πŸ’‘ Feature suggestions
  • πŸ“ Documentation improvements
  • πŸ”§ Code contributions

Please feel free to open an issue or submit a pull request.

πŸ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ“š Additional Resources #


Made with ❀️ by Godfrey Lebo

If this package helps secure your app, consider giving it a ⭐ on GitHub!

2
likes
150
points
85
downloads

Publisher

verified publishergodfreylebo.dev

Weekly Downloads

A Flutter package for biometric-protected encryption of small secrets using Android Keystore and iOS Keychain/Secure Enclave.

Repository (GitHub)
View/report issues

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on flutter_biometric_crypto

Packages that implement flutter_biometric_crypto