Skip to content

A lightweight and unified React Native library for biometric authentication across iOS and Android. Supports Face ID, Touch ID, and Fingerprint with a simple JavaScript API.

License

Notifications You must be signed in to change notification settings

wellth-app/react-native-biometrics

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

49 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ” React Native Biometrics

A lightweight and unified React Native library for biometric authentication across iOS and Android

npm version downloads license stars typescript

iOS Support Android Support New Architecture

🎬 Demo

React Native Biometrics Demo React Native Biometrics Demo

✨ Features

  • πŸ”’ Unified API - Single interface for iOS and Android biometric authentication
  • πŸ“± Multiple Biometric Types - Face ID, Touch ID, Fingerprint, and more
  • πŸ› οΈ Advanced Options - Customizable prompts, fallback options, and device credentials
  • πŸ”‘ Key Management - Create and manage cryptographic keys for secure operations
  • πŸ›‘οΈ Device Integrity - Detect compromised devices (rooted/jailbroken) for enhanced security
  • πŸ› Debug Tools - Comprehensive diagnostic and testing utilities
  • πŸ“ Centralized Logging - Advanced logging system for debugging and monitoring
  • πŸ” Key Integrity Validation - Comprehensive cryptographic key validation and signature verification
  • πŸ“¦ Lightweight - Minimal dependencies and optimized for performance
  • 🎯 TypeScript - Full TypeScript support with detailed type definitions
  • πŸ”„ New Architecture - Compatible with React Native's new architecture (TurboModules)
  • βœ… Old Architecture - Compatible with React Native's old architecture
  • 🌟 Expo Compatible - Works seamlessly with Expo development workflow
  • πŸ“± Modern - Made with Swift and Kotlin for iOS and Android respectively
  • πŸš€ Easy Integration - Simple setup with comprehensive documentation
  • πŸ” Secure by Default - Industry-standard security practices built-in

πŸ“‹ Requirements

Platform Minimum Version Recommended
React Native 0.68+ 0.75+

Supported Biometric Types

  • iOS: Face ID, Touch ID
  • Android: Fingerprint, Face Recognition, Iris Scanner
  • Fallback: Device PIN, Password, Pattern

πŸš€ Installation

NPM

npm install @sbaiahmed1/react-native-biometrics

Yarn

yarn add @sbaiahmed1/react-native-biometrics

iOS Setup

  1. Add permissions to Info.plist:
<key>NSFaceIDUsageDescription</key>
<string>This app uses Face ID for secure authentication</string>
  1. Install iOS dependencies:
cd ios && pod install

Android Setup

  1. Add permissions to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
  1. Ensure minimum SDK version in android/app/build.gradle:
android {
    compileSdkVersion 34
    defaultConfig {
        minSdkVersion 23
        targetSdkVersion 34
    }
}
  1. Add ProGuard rules (if using ProGuard) in android/app/proguard-rules.pro:
-keep class androidx.biometric.** { *; }
-keep class com.sbaiahmed1.reactnativebiometrics.** { *; }

πŸ“– Usage

πŸ” Quick Start

import {
  isSensorAvailable,
  simplePrompt,
  authenticateWithOptions,
  setDebugMode
} from '@sbaiahmed1/react-native-biometrics';

const BiometricAuth = () => {
  const authenticate = async () => {
    try {
      // Enable debug mode for development
      await setDebugMode(true);

      // Check if biometric authentication is available
      const sensorInfo = await isSensorAvailable();

      if (sensorInfo.available) {
        console.log(`βœ… ${sensorInfo.biometryType} available`);

        // Perform authentication
        const result = await simplePrompt('Please authenticate to continue');

        if (result) {
          console.log('πŸŽ‰ Authentication successful!');
          // Navigate to secure content
        } else {
          console.log('❌ Authentication failed');
        }
      } else {
        console.log('❌ Biometric authentication not available:', sensorInfo.error);
        // Show alternative authentication method
      }
    } catch (error) {
      console.error('πŸ’₯ Authentication error:', error);
    }
  };

  return authenticate;
};

πŸ” Check Sensor Availability

Before attempting authentication, check if biometric sensors are available on the device.

import { isSensorAvailable } from '@sbaiahmed1/react-native-biometrics';

const checkBiometrics = async () => {
  try {
    const sensorInfo = await isSensorAvailable();

    if (sensorInfo.available) {
      console.log('βœ… Biometric authentication available');
      console.log('πŸ“± Type:', sensorInfo.biometryType);
      // Possible values: 'FaceID', 'TouchID', 'Fingerprint', 'Biometrics'
    } else {
      console.log('❌ Biometric authentication not available');
      console.log('🚫 Reason:', sensorInfo.error);
    }
  } catch (error) {
    console.error('πŸ’₯ Error checking biometrics:', error);
  }
};

πŸ” Simple Authentication

Perform basic biometric authentication with a custom message.

import { simplePrompt } from '@sbaiahmed1/react-native-biometrics';

const authenticate = async () => {
  try {
    const result = await simplePrompt('Please authenticate to continue');

    if (result) {
      console.log('βœ… Authentication successful!');
      // Proceed with authenticated action
    } else {
      console.log('❌ Authentication failed or cancelled');
    }
  } catch (error) {
    console.error('πŸ’₯ Authentication error:', error);
  }
};

βš™οΈ Enhanced Authentication

Use advanced authentication options with customizable prompts and fallback mechanisms.

import { authenticateWithOptions } from '@sbaiahmed1/react-native-biometrics';

const enhancedAuth = async () => {
  try {
    const result = await authenticateWithOptions({
      title: 'πŸ” Secure Login',
      subtitle: 'Verify your identity',
      description: 'Use your biometric to access your account securely',
      cancelLabel: 'Cancel',
      fallbackLabel: 'Use Password',
      allowDeviceCredentials: true,    // Allow PIN/password fallback
      disableDeviceFallback: false,    // Enable fallback options
    });

    if (result.success) {
      console.log('βœ… Authentication successful!');
      // User authenticated successfully
      navigateToSecureArea();
    } else {
      console.log('❌ Authentication failed:', result.error);
      console.log('πŸ”’ Error code:', result.errorCode);
      // Handle authentication failure
      handleAuthFailure(result.errorCode);
    }
  } catch (error) {
    console.error('πŸ’₯ Authentication error:', error);
  }
};

// Example: Different authentication scenarios
const authScenarios = {
  // Strict biometric only (no fallback)
  strictBiometric: {
    title: 'Biometric Required',
    subtitle: 'Touch sensor or look at camera',
    allowDeviceCredentials: false,
    disableDeviceFallback: true,
  },

  // Flexible authentication (with fallbacks)
  flexibleAuth: {
    title: 'Secure Access',
    subtitle: 'Use biometric or device passcode',
    allowDeviceCredentials: true,
    disableDeviceFallback: false,
    fallbackLabel: 'Use Passcode',
  },

  // Custom branded experience
  brandedAuth: {
    title: 'MyApp Security',
    subtitle: 'Protect your data',
    description: 'Authenticate to access your personal information',
    cancelLabel: 'Not Now',
    fallbackLabel: 'Enter PIN',
  },
 };

πŸ”‘ Key Management

Manage cryptographic keys for secure biometric operations.

import { createKeys, deleteKeys, getAllKeys } from '@sbaiahmed1/react-native-biometrics';

// Create biometric keys for secure operations
const createBiometricKeys = async () => {
  try {
    const result = await createKeys();
    console.log('βœ… Keys created successfully');
    console.log('πŸ”‘ Public key:', result.publicKey);

    // Store the public key for server-side verification
    await storePublicKeyOnServer(result.publicKey);
  } catch (error) {
    console.error('πŸ’₯ Failed to create keys:', error);
  }
};

// Delete biometric keys when no longer needed
const deleteBiometricKeys = async () => {
  try {
    const result = await deleteKeys();

    if (result.success) {
      console.log('βœ… Keys deleted successfully');
      // Clean up any stored references
      await removePublicKeyFromServer();
    } else {
      console.log('❌ Failed to delete keys');
    }
  } catch (error) {
    console.error('πŸ’₯ Failed to delete keys:', error);
  }
};

// Retrieve all stored biometric keys
const getAllBiometricKeys = async () => {
  try {
    const result = await getAllKeys();

    console.log(`πŸ“‹ Found ${result.keys.length} stored keys`);

    result.keys.forEach((key, index) => {
      console.log(`πŸ”‘ Key ${index + 1}:`);
      console.log(`   Alias: ${key.alias}`);
      console.log(`   Public Key: ${key.publicKey.substring(0, 50)}...`);
      if (key.creationDate) {
        console.log(`   Created: ${key.creationDate}`);
      }
    });

    return result.keys;
  } catch (error) {
    console.error('πŸ’₯ Failed to retrieve keys:', error);
    return [];
  }
};

// Example: Complete key lifecycle management
const keyLifecycleExample = async () => {
  try {
    // 1. Check if biometrics are available
    const sensorInfo = await isSensorAvailable();
    if (!sensorInfo.available) {
      throw new Error('Biometric authentication not available');
    }

    // 2. Create keys for the user
    const keyResult = await createKeys();
    console.log('πŸ” Biometric keys created for user');

    // 3. Perform authenticated operations
    const authResult = await authenticateWithOptions({
      title: 'Verify Identity',
      subtitle: 'Authenticate to access secure features',
    });

    if (authResult.success) {
      console.log('πŸŽ‰ User authenticated with biometric keys');
    }

    // 4. Clean up when user logs out
    // await deleteKeys();
  } catch (error) {
    console.error('πŸ’₯ Key lifecycle error:', error);
  }
};

πŸ› Debugging Utilities

Comprehensive debugging tools to help troubleshoot biometric authentication issues.

import {
  getDiagnosticInfo,
  runBiometricTest,
  setDebugMode
} from '@sbaiahmed1/react-native-biometrics';

// πŸ” Get comprehensive diagnostic information
const getDiagnostics = async () => {
  try {
    const info = await getDiagnosticInfo();

    console.log('πŸ“± Platform:', info.platform);
    console.log('πŸ”’ OS Version:', info.osVersion);
    console.log('πŸ“² Device Model:', info.deviceModel);
    console.log('πŸ” Biometric Capabilities:', info.biometricCapabilities);
    console.log('πŸ›‘οΈ Security Level:', info.securityLevel);
    console.log('πŸ”’ Keyguard Secure:', info.keyguardSecure);
    console.log('πŸ‘† Enrolled Biometrics:', info.enrolledBiometrics);

    if (info.lastError) {
      console.log('⚠️ Last Error:', info.lastError);
    }

    return info;
  } catch (error) {
    console.error('πŸ’₯ Failed to get diagnostic info:', error);
  }
};

// πŸ§ͺ Run comprehensive biometric functionality test
const testBiometrics = async () => {
  try {
    console.log('πŸ§ͺ Running biometric tests...');
    const testResult = await runBiometricTest();

    if (testResult.success) {
      console.log('βœ… All tests passed!');
    } else {
      console.log('❌ Test failures detected:');
      testResult.errors.forEach(error => console.log('  🚫', error));

      if (testResult.warnings.length > 0) {
        console.log('⚠️ Test warnings:');
        testResult.warnings.forEach(warning => console.log('  ⚠️', warning));
      }
    }

    // Detailed test results
    console.log('πŸ“Š Test Results:');
    console.log('  πŸ” Sensor Available:', testResult.results.sensorAvailable);
    console.log('  πŸ” Can Authenticate:', testResult.results.canAuthenticate);
    console.log('  πŸ”§ Hardware Detected:', testResult.results.hardwareDetected);
    console.log('  πŸ‘† Has Enrolled Biometrics:', testResult.results.hasEnrolledBiometrics);
    console.log('  πŸ›‘οΈ Secure Hardware:', testResult.results.secureHardware);

    return testResult;
  } catch (error) {
    console.error('πŸ’₯ Failed to run biometric test:', error);
  }
};

// πŸ”§ Debug mode management
const debugModeExample = async () => {
  try {
    // Enable debug logging
    await setDebugMode(true);
    console.log('πŸ› Debug mode enabled - all operations will be logged');

    // Perform some operations (they will now be logged)
    await isSensorAvailable();
    await simplePrompt('Debug test authentication');

    // Disable debug logging
    await setDebugMode(false);
    console.log('πŸ”‡ Debug mode disabled');
  } catch (error) {
    console.error('πŸ’₯ Failed to manage debug mode:', error);
  }
};

// πŸ” Complete diagnostic workflow
const runDiagnosticWorkflow = async () => {
  console.log('πŸš€ Starting comprehensive biometric diagnostics...');

  // 1. Enable debug mode
  await setDebugMode(true);

  // 2. Get device information
  const diagnostics = await getDiagnostics();

  // 3. Run functionality tests
  const testResults = await testBiometrics();

  // 4. Generate report
  const report = {
    timestamp: new Date().toISOString(),
    device: diagnostics,
    tests: testResults,
    summary: {
      isFullyFunctional: testResults?.success || false,
      criticalIssues: testResults?.errors?.length || 0,
      warnings: testResults?.warnings?.length || 0,
    }
  };

  console.log('πŸ“‹ Diagnostic Report:', JSON.stringify(report, null, 2));

  // 5. Disable debug mode
  await setDebugMode(false);

  return report;
};

πŸ“š API Reference

Configuration Methods

configureKeyAlias(keyAlias: string)

Configures a custom key alias for biometric key storage. This enhances security by allowing app-specific key aliases instead of using a shared hardcoded alias.

import { configureKeyAlias } from '@sbaiahmed1/react-native-biometrics';

// Configure a custom key alias
await configureKeyAlias('com.myapp.biometric.main');

getDefaultKeyAlias()

Returns the current default key alias. If no custom alias is configured, returns an app-specific default based on bundle ID (iOS) or package name (Android).

import { getDefaultKeyAlias } from '@sbaiahmed1/react-native-biometrics';

const defaultAlias = await getDefaultKeyAlias();
console.log('Current key alias:', defaultAlias);

configure(config: BiometricConfig)

Configures the library with a configuration object.

import { configure } from '@sbaiahmed1/react-native-biometrics';

await configure({
  keyAlias: 'com.myapp.biometric.main'
});

Core Functions

isSensorAvailable()

Checks if biometric authentication is available on the device.

const isSensorAvailable = (): Promise<SensorInfo> => {
};

type SensorInfo = {
  available: boolean;        // Whether biometric auth is available
  biometryType?: string;     // Type of biometry ('FaceID', 'TouchID', 'Fingerprint', etc.)
  error?: string;            // Error message if not available
}

simplePrompt(reason: string)

Performs basic biometric authentication with a custom message.

const simplePrompt = (reason: string): Promise<boolean> => {
};

Parameters:

  • reason (string): Message to display to the user

Returns: Promise<boolean> - true if authentication succeeded, false otherwise

authenticateWithOptions(options)

Enhanced authentication with customizable options and detailed results.

const authenticateWithOptions = (options: AuthOptions): Promise<AuthResult> => {
};

type AuthOptions = {
  title?: string;                    // Dialog title
  subtitle?: string;                 // Dialog subtitle
  description?: string;              // Additional description
  cancelLabel?: string;              // Cancel button text
  fallbackLabel?: string;            // Fallback button text
  allowDeviceCredentials?: boolean;  // Allow PIN/password fallback
  disableDeviceFallback?: boolean;   // Disable fallback options
}

type AuthResult = {
  success: boolean;          // Authentication result
  error?: string;            // Error message if failed
  errorCode?: string;        // Error code if failed
}

Key Management

createKeys(keyAlias?: string)

Generates cryptographic keys for secure biometric operations. Optionally accepts a custom key alias.

const createKeys = (keyAlias?: string): Promise<KeyResult> => {
};

type KeyResult = {
  publicKey: string;         // Generated public key
}

Example:

import { createKeys } from '@sbaiahmed1/react-native-biometrics';

// Create keys with default (configured) alias
try {
  const result = await createKeys();
  console.log('Keys created successfully:', result.publicKey);
} catch (error) {
  console.error('Error creating keys:', error);
}

// Create keys with custom alias
try {
  const result = await createKeys('com.myapp.biometric.backup');
  console.log('Keys created with custom alias:', result.publicKey);
} catch (error) {
  console.error('Error creating keys:', error);
}

deleteKeys(keyAlias?: string)

Deletes previously created cryptographic keys. Optionally accepts a custom key alias.

const deleteKeys = (keyAlias?: string): Promise<DeleteResult> => {
};

type DeleteResult = {
  success: boolean;          // Whether deletion succeeded
}

Example:

import { deleteKeys } from '@sbaiahmed1/react-native-biometrics';

// Delete keys with default (configured) alias
try {
  const result = await deleteKeys();
  console.log('Keys deleted successfully');
} catch (error) {
  console.error('Error deleting keys:', error);
}

// Delete keys with custom alias
try {
  const result = await deleteKeys('com.myapp.biometric.backup');
  console.log('Keys deleted with custom alias');
} catch (error) {
  console.error('Error deleting keys:', error);
}

getAllKeys()

Retrieves all stored cryptographic keys.

const getAllKeys = (): Promise<GetAllKeysResult> => {
};

type GetAllKeysResult = {
  keys: Array<{
    alias: string;           // Key identifier/alias
    publicKey: string;       // Base64 encoded public key
    creationDate?: string;   // Key creation date (if available)
  }>;
}

Device Security

getDeviceIntegrityStatus()

Checks the integrity and security status of the device, including detection of compromised devices (rooted/jailbroken).

const getDeviceIntegrityStatus = (): Promise<DeviceIntegrityResult> => {
};

type DeviceIntegrityResult = {
  // Platform-specific properties
  isRooted?: boolean;           // πŸ€– ANDROID ONLY: Whether device is rooted
  isJailbroken?: boolean;       // 🍎 iOS ONLY: Whether device is jailbroken
  isKeyguardSecure?: boolean;   // πŸ€– ANDROID ONLY: Whether device lock is secure
  hasSecureHardware?: boolean;  // πŸ€– ANDROID ONLY: Whether secure hardware is available

  // Cross-platform properties
  isCompromised: boolean;       // πŸ€–πŸŽ Overall compromise status (always present)
  riskLevel: 'NONE' | 'LOW' | 'MEDIUM' | 'HIGH' | 'UNKNOWN';  // πŸ€–πŸŽ Risk assessment (always present)
  error?: string;               // πŸ€–πŸŽ Error message if check failed
}

Example:

import { getDeviceIntegrityStatus } from '@sbaiahmed1/react-native-biometrics';

const checkDeviceSecurity = async () => {
  try {
    const status = await getDeviceIntegrityStatus();

    if (status.isCompromised) {
      console.warn('⚠️ Device security compromised!');
      console.log('Risk level:', status.riskLevel);

      if (status.isRooted) {
        // Android ONLY
        console.log('πŸ“± Device is rooted');
      }

      if (status.isJailbroken) {
        // IOS ONLY
        console.log('πŸ“± Device is jailbroken');
      }

      // Handle compromised device (e.g., restrict functionality)
      return false;
    } else {
      console.log('βœ… Device security intact');
      console.log('Risk level:', status.riskLevel);
      return true;
    }
  } catch (error) {
    console.error('πŸ’₯ Device integrity check failed:', error);
    return false;
  }
};

Platform Compatibility:

Property Android iOS Description
isRooted βœ… ❌ Detects if Android device is rooted
isJailbroken ❌ βœ… Detects if iOS device is jailbroken
isKeyguardSecure βœ… ❌ Checks if device lock screen is secure
hasSecureHardware βœ… ❌ Verifies secure hardware availability
isCompromised βœ… βœ… Overall security compromise status
riskLevel βœ… βœ… Risk assessment level
error βœ… βœ… Error message if check fails

Security Considerations:

  • Device integrity checks are not foolproof and can be bypassed by sophisticated attackers
  • Use this as an additional security layer, not as the sole security measure
  • Consider implementing server-side validation for critical operations
  • The risk level assessment helps you make informed decisions about feature restrictions
  • Platform-specific properties (isRooted/isJailbroken) will be undefined on the opposite platform

Debugging & Diagnostics

getDiagnosticInfo()

Returns comprehensive diagnostic information about the device's biometric capabilities.

const getDiagnosticInfo = (): Promise<DiagnosticInfo> => {
};

type DiagnosticInfo = {
  platform: string;                 // 'iOS' or 'Android'
  osVersion: string;                // Operating system version
  deviceModel: string;              // Device model information
  biometricCapabilities: string[];  // Available biometric types
  securityLevel: string;            // 'SecureHardware' or 'Software'
  keyguardSecure: boolean;          // Whether device lock is secure
  enrolledBiometrics: string[];     // Currently enrolled biometric types
  lastError?: string;               // Last error encountered (if any)
}

runBiometricTest()

Runs a comprehensive test of biometric functionality and returns detailed results.

const runBiometricTest = (): Promise<BiometricTestResult> => {
};

type BiometricTestResult = {
  success: boolean;                 // Overall test success
  results: {
    sensorAvailable: boolean;         // Biometric sensor availability
    canAuthenticate: boolean;         // Authentication capability
    hardwareDetected: boolean;        // Hardware detection
    hasEnrolledBiometrics: boolean;   // Enrolled biometrics check
    secureHardware: boolean;          // Secure hardware availability
  };
  errors: string[];                 // Critical errors found
  warnings: string[];               // Non-critical warnings
}

setDebugMode(enabled: boolean)

Enables or disables debug logging for the biometric library.

const setDebugMode = (enabled: boolean): Promise<void> => {
};

Parameters:

  • enabled (boolean): Whether to enable debug mode

Usage:

  • When enabled, all library operations will log detailed information
  • iOS: Check Xcode console for [ReactNativeBiometrics Debug] messages
  • Android: Check Logcat for ReactNativeBiometrics Debug tags

Logging & Monitoring

The library includes a comprehensive centralized logging system for debugging and monitoring biometric operations.

enableLogging(enabled: boolean)

Enables or disables the centralized logging system.

const enableLogging = (enabled: boolean): void => {
};

setLogLevel(level: LogLevel)

Sets the minimum log level for output.

enum LogLevel {
  DEBUG = 0,
  INFO = 1,
  WARN = 2,
  ERROR = 3
}

const setLogLevel = (level: LogLevel): void => {
};

configureLogger(config: LoggerConfig)

Configures the logger with advanced options.

type LoggerConfig = {
  enabled: boolean;
  level: LogLevel;
  useColors: boolean;
  prefix: string;
  includeTimestamp: boolean;
  includeContext: boolean;
  maxStoredLogs: number;
};

const configureLogger = (config: Partial<LoggerConfig>): void => {
};

getStoredLogs()

Retrieves stored log entries for analysis.

type LogEntry = {
  timestamp: string;
  level: LogLevel;
  message: string;
  context?: string;
};

const getStoredLogs = (): LogEntry[] => {
};

clearStoredLogs()

Clears all stored log entries.

const clearStoredLogs = (): void => {
};

Example Usage:

import {
  enableLogging,
  setLogLevel,
  LogLevel,
  configureLogger,
  getStoredLogs
} from '@sbaiahmed1/react-native-biometrics';

// Enable logging with INFO level
enableLogging(true);
setLogLevel(LogLevel.INFO);

// Configure advanced logging options
configureLogger({
  useColors: true,
  prefix: '[MyApp]',
  includeTimestamp: true,
  includeContext: true,
  maxStoredLogs: 1000
});

// Perform biometric operations - they will be automatically logged
const sensorInfo = await isSensorAvailable();

// Retrieve logs for analysis
const logs = getStoredLogs();
console.log('Recent logs:', logs);

For detailed logging documentation, see docs/LOGGING.md.

Key Integrity Validation

validateKeyIntegrity(keyAlias?: string): Promise<KeyIntegrityResult>

Performs comprehensive validation of key integrity including format checks, accessibility tests, signature validation, and hardware backing verification.

verifyKeySignature(data: string, keyAlias?: string): Promise<SignatureResult>

Generates a cryptographic signature for the provided data using the specified key.

validateSignature(data: string, signature: string, keyAlias?: string): Promise<SignatureValidationResult>

Validates a signature against the original data using the public key.

getKeyAttributes(keyAlias?: string): Promise<KeyAttributesResult>

Retrieves detailed attributes and security properties of the specified key.

Example:

import {
  validateKeyIntegrity,
  verifyKeySignature,
  validateSignature,
  getKeyAttributes
} from '@sbaiahmed1/react-native-biometrics';

// Validate key integrity
const integrityResult = await validateKeyIntegrity('my-key');
console.log('Key valid:', integrityResult.valid);
console.log('Hardware backed:', integrityResult.integrityChecks.hardwareBacked);

// Generate and validate signature
const data = 'Hello, secure world!';
const signatureResult = await verifyKeySignature(data, 'my-key');
if (signatureResult.success) {
  const validationResult = await validateSignature(data, signatureResult.signature, 'my-key');
  console.log('Signature valid:', validationResult.valid);
}

// Get key attributes
const attributes = await getKeyAttributes('my-key');
if (attributes.exists) {
  console.log('Algorithm:', attributes.attributes.algorithm);
  console.log('Key size:', attributes.attributes.keySize);
  console.log('Security level:', attributes.attributes.securityLevel);
}

Error Codes

Common error codes returned by authentication methods:

Code Description Platform
SENSOR_NOT_AVAILABLE Biometric sensor not available Both
USER_CANCEL User cancelled authentication Both
USER_FALLBACK User chose fallback method Both
SYSTEM_CANCEL System cancelled authentication Both
PASSCODE_NOT_SET Device passcode not set Both
BIOMETRY_NOT_AVAILABLE Biometry not available iOS
BIOMETRY_NOT_ENROLLED No biometrics enrolled iOS
BIOMETRY_LOCKOUT Too many failed attempts Both

πŸ“± Example App

The library includes a comprehensive example app demonstrating all features and capabilities. The example app contains several demo components:

Available Demo Components

πŸ” AuthExample

Demonstrates basic authentication flows:

  • Simple biometric prompts
  • Enhanced authentication with custom options
  • Error handling and fallback scenarios

🎨 ColorExample

Shows UI customization capabilities:

  • Custom prompt styling
  • Theme integration
  • Visual feedback examples

πŸ”§ CombinedBiometricsDemo

Comprehensive demonstration of key management and security features:

  • Key Management: Create, delete, and list biometric keys with custom aliases
  • Integrity Validation: Comprehensive key integrity checks and validation
  • Signature Operations: Generate and verify cryptographic signatures
  • Security Testing: Automated test suite for all security features
  • Real-time Results: Live display of test results and security status

This component combines the functionality of key management and integrity testing into a single, unified interface, making it easy to test and understand all security features.

πŸ› DebuggingExample

Debugging and diagnostic utilities:

  • Device capability detection
  • Comprehensive diagnostic information
  • Debug logging controls
  • Test result analysis

Running the Example App

cd example
npm install

# iOS
cd ios && pod install && cd ..
npx react-native run-ios

# Android
npx react-native run-android

The example app provides hands-on experience with all library features and serves as a reference implementation for integration patterns.

πŸ“Š Library Comparison

Feature @sbaiahmed1/react-native-biometrics react-native-biometrics react-native-touch-id
TypeScript Support βœ… Full support ❌ Limited ❌ No
New Architecture βœ… TurboModules ❌ No ❌ No
Expo Compatibility βœ… Yes ❌ No ❌ No
Key Management βœ… Advanced βœ… Basic ❌ No
Debug Tools βœ… Comprehensive ❌ Limited ❌ No
Active Maintenance βœ… Yes ❌ Outdated ❌ Outdated
Bundle Size 🟒 Small 🟑 Medium 🟒 Small
Documentation βœ… Extensive 🟑 Basic 🟑 Basic
Security Features βœ… Advanced 🟑 Basic 🟑 Basic

🎯 Use Cases

Mobile Banking & Finance

  • Secure login for banking applications
  • Transaction authentication
  • Account access protection
  • Compliance with financial security standards

Healthcare Applications

  • Patient data access control
  • Medical record security
  • HIPAA compliance support
  • Secure prescription management

Enterprise & Business

  • Employee authentication
  • Corporate app security
  • Document access control
  • Time tracking applications

E-commerce & Retail

  • Secure payment authentication
  • Account protection
  • Purchase confirmation
  • Loyalty program access

Social & Communication

  • Private message protection
  • Profile security
  • Content access control
  • Privacy-focused features

πŸ”§ Troubleshooting

Common Issues

iOS

  • "Biometry is not available": Ensure Face ID/Touch ID is set up in device settings
  • "Passcode not set": Device must have a passcode/password configured
  • Build errors: Make sure iOS deployment target is 11.0 or higher

Android

  • "No biometric features available": Check if device has fingerprint sensor and it's enrolled
  • "BiometricPrompt not available": Ensure Android API level 23+ and androidx.biometric dependency
  • Permission denied: Verify USE_FINGERPRINT and USE_BIOMETRIC permissions are added

Debug Mode

Enable debug mode to get detailed logs:

import ReactNativeBiometrics from '@sbaiahmed1/react-native-biometrics';

// Enable debug logging
await ReactNativeBiometrics.setDebugMode(true);

// Perform operations - check console for detailed logs
const result = await ReactNativeBiometrics.isSensorAvailable();

// Disable when done
await ReactNativeBiometrics.setDebugMode(false);

Getting Help

  1. Check the troubleshooting section above
  2. Run diagnostic tests using getDiagnosticInfo() and runBiometricTest()
  3. Enable debug mode for detailed logging
  4. Search existing GitHub issues
  5. Create a new issue with:
    • Device information
    • OS version
    • Library version
    • Debug logs
    • Minimal reproduction code

🀝 Contributing

We welcome contributions! Here's how you can help:

Development Setup

  1. Fork and clone the repository

    git clone https://github.com/your-username/react-native-biometrics.git
    cd react-native-biometrics
  2. Install dependencies

    npm install
    # or
    yarn install

Guidelines

  • πŸ› Bug Reports: Include device info, OS version, and reproduction steps
  • ✨ Feature Requests: Describe the use case and expected behavior
  • πŸ”§ Pull Requests:
    • Follow existing code style
    • Add tests for new features
    • Update documentation
    • Test on both iOS and Android

Code Style

  • Use TypeScript for type safety
  • Follow existing naming conventions
  • Add JSDoc comments for public APIs
  • Ensure debug logging for new methods

πŸ”’ Security

This library implements several security measures:

  • Hardware-backed keys: Uses the device's secure hardware when available
  • Biometric validation: Requires actual biometric authentication
  • Key isolation: Keys are stored in the device's secure keystore
  • No key export: Private keys never leave the secure hardware
  • App-specific key aliases: Each app uses unique key aliases to prevent cross-app key access

Key Alias Security Enhancement

Previous versions used a hardcoded key alias ("ReactNativeBiometricsKey") shared across all apps, which posed security risks:

  • Multiple apps could potentially access each other's biometric keys
  • Key collisions could occur between different applications

Current version implements secure, app-specific key aliases:

  • Default aliases are automatically generated using bundle ID (iOS) or package name (Android)
  • Custom aliases can be configured for different security contexts
  • Key isolation ensures each app's biometric keys are properly separated
// Configure app-specific key alias
await configureKeyAlias('com.myapp.biometric.main');

// Get current default alias (auto-generated if not configured)
const alias = await getDefaultKeyAlias();
// Returns: "com.myapp.ReactNativeBiometrics"

For detailed security information, see KEY_ALIAS_SECURITY.md.

πŸ“„ License

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


πŸš€ Roadmap

βœ… Completed

  • Code Quality Improvements: Improved type safety, error handling, and code documentation
  • Type Safety: Fixed conditional casting warnings and type conversion issues
  • Code Organization: Added MARK comments and improved code structure
  • Enhanced Testing: Expand unit test coverage and add integration tests
  • Centralized Logging: Implemented comprehensive logging and error reporting system
  • Advanced Security Features: Enhanced security measures and validation

πŸ”„ In Progress

  • Biometrics Change Event Handling: Implement event listeners for biometric changes (e.g., new enrollment, removal)
  • Performance Optimization: Optimize biometric operations and reduce latency

πŸ™ Acknowledgments

πŸ“Š Stats

contributors last commit issues pull requests

Made with ❀️ by @sbaiahmed1

⭐ Star this repo if it helped you!

Report Bug Β· Request Feature Β· Discussions

About

A lightweight and unified React Native library for biometric authentication across iOS and Android. Supports Face ID, Touch ID, and Fingerprint with a simple JavaScript API.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 43.0%
  • Kotlin 30.2%
  • Swift 23.4%
  • JavaScript 1.3%
  • Ruby 1.0%
  • Objective-C++ 1.0%
  • Objective-C 0.1%