npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

rn-secure-keystore

v1.0.0

Published

A comprehensive, cross-platform React Native wrapper for secure key-value storage using native security features of Android and iOS. It supports **biometric authentication**, **hardware-backed encryption**, and deep platform integrations such as **Android

Readme

rn-secure-keystore

A comprehensive, cross-platform React Native wrapper for secure key-value storage using native security features of Android and iOS. It supports biometric authentication, hardware-backed encryption, and deep platform integrations such as Android StrongBox, EncryptedSharedPreferences, and iOS Secure Enclave via the Keychain.

This library enables storing data securely with biometric protection, ensuring that sensitive information can only be accessed after successful biometric verification (e.g., fingerprint or face recognition). This adds an additional layer of security by requiring user authentication to retrieve or modify protected data, making it ideal for handling highly sensitive data.

Features

  • Hardware-backed security – Utilizes device secure elements when available
  • Biometric authentication – Store and retrieve data with biometric protection
  • Cross-platform – Works on both iOS and Android with platform-specific optimizations
  • StrongBox support (Android only) – Enhanced protection using dedicated security chips
  • iOS Keychain integration – Access to iOS Keychain access controls
  • Secure storage – Store sensitive data like tokens, passwords, and user credentials
  • Error handling – Comprehensive error codes and recovery mechanisms
  • Security introspection – Check security levels and platform capabilities
  • Fallback mechanisms – Graceful degradation when advanced features aren't available

📦 Installation

npm install rn-secure-keystore

iOS Setup

cd ios && pod install

Add the following to your Info.plist:

<key>NSFaceIDUsageDescription</key>
<string>Use Face ID to authenticate and access secure data</string>

Android Setup

Ensure your android/app/build.gradle has minimum SDK version 23:

android {
    compileSdkVersion 34
    defaultConfig {
        minSdkVersion 23
        // ...
    }
}

Add biometric permissions to android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />

Note: This library requires native modules and will not work with Expo Go.

Platform-Level Security Features

iOS – Secure Enclave & Keychain

On iOS, all data is securely stored using the native Keychain. For devices with Secure Enclave (iPhone 5s and later), encryption is hardware-backed, meaning your secrets are tied to the physical chip and are secure.

Key benefits:

  • Secure Enclave for hardware-backed storage
  • Support for access groups and keychain sharing between apps
  • Advanced access control options
  • Hardware backing when available

Android – EncryptedSharedPreferences & StrongBox

EncryptedSharedPreferences

This library uses Android Jetpack's EncryptedSharedPreferences with fallback to regular SharedPreferences, which combines:

  • A master key stored in Android's Keystore
  • AES encryption for your key-value pairs
  • Automatic key generation and rotation
  • Graceful fallback for compatibility

StrongBox

On supported devices (API 28+), you can optionally store encryption keys in StrongBox, a hardware security module (HSM) separate from the main CPU. This provides maximum protection, especially against physical tampering.

  • Resistant to rooting and debugging
  • Keys stored in StrongBox are non-exportable
  • Enforced user authentication (e.g., biometrics) via hardware-backed checks
  • Fallback to TEE (Trusted Execution Environment) if StrongBox is unavailable

StrongBox is only available on select newer Android devices with a dedicated secure element (Pixel 3+, Samsung S9+, etc.).

🔐 Security Levels

Android Security Tiers

| Level | Description | Use Case | | ----------- | -------------------------------------------------------- | -------------------- | | strongbox | Stored in StrongBox HSM; maximum protection if available | Ultra-sensitive data | | hardware | Backed by Trusted Execution Environment (TEE) | Sensitive data | | software | Software-encrypted; fallback for older devices | Basic protection | | auto | Automatically chooses the strongest supported level | Recommended default |

iOS Security

  • iOS Keychain automatically uses hardware-backed encryption when the device supports Secure Enclave
  • Hardware backing is transparent and automatic on supported iOS devices

Quick Start

Basic Usage

import SecureStorage from 'rn-secure-keystore';

// Store a value
await SecureStorage.setItem('userToken', 'abc123');

// Retrieve a value
const token = await SecureStorage.getItem('userToken');

// Check if a key exists
const exists = await SecureStorage.hasItem('userToken');

// Remove a value
await SecureStorage.removeItem('userToken');

// Get all keys
const keys = await SecureStorage.getAllKeys();

// Clear all data
await SecureStorage.clear();

Biometric Authentication

// Store with biometric protection
await SecureStorage.setItem('sensitiveData', 'secret', {
  withBiometric: true,
  authenticatePrompt: 'Authenticate to store sensitive data',
  authenticatePromptSubtitle:
    'Use your fingerprint or face to secure this data',
});

// Retrieve with biometric authentication
const data = await SecureStorage.getItem('sensitiveData', {
  authenticatePrompt: 'Authenticate to access sensitive data',
  authenticatePromptSubtitle: 'Use your biometric to continue',
});

Platform-Specific Features

Android – Advanced Security Options

// Check device capabilities
const capabilities = await SecureStorage.getPlatformCapabilities();
console.log('StrongBox available:', capabilities.hasStrongBox);

// Store with specific security level
await SecureStorage.setItem('data', 'value', {
  securityLevel: 'strongbox', // 'strongbox' | 'hardware' | 'software' | 'auto'
  allowFallback: true, // Allow fallback if StrongBox not available
});

// Use convenience method for StrongBox
await SecureStorage.setStrongBoxItem('ultraSecure', 'data', true);

// Get recommended security level
const recommendedLevel = await SecureStorage.getRecommendedSecurityLevel();

iOS – Keychain Access Control

import SecureStorage, { ACCESS_CONTROL } from 'rn-secure-keystore';

// Store with specific access control (no biometric required for basic storage)
await SecureStorage.setItem('basicData', 'value');

// Store with biometric requirement
await SecureStorage.setItem('biometricData', 'secret', {
  accessControl: ACCESS_CONTROL.BIOMETRY_ANY_OR_DEVICE_PASSCODE,
  authenticatePrompt: 'Authenticate to store data',
});

// Use convenience method
await SecureStorage.setKeychainItem(
  'keychainData',
  'secret',
  ACCESS_CONTROL.BIOMETRY_CURRENT_SET,
  'com.yourapp.shared' // access group (optional)
);

Security Introspection

// Check individual key security
const isHardwareBacked = await SecureStorage.isKeyHardwareBacked('myKey');
const securityLevel = await SecureStorage.getKeySecurityLevel('myKey');

// Get security status for all keys
const securityStatus = await SecureStorage.getSecurityStatus();
console.log('All keys security:', securityStatus);

// Check if device meets requirements
const requirements = {
  requireBiometric: true,
  requireHardwareBacking: true,
  requireStrongBox: false,
};
const { meets, missing } =
  await SecureStorage.meetsSecurityRequirements(requirements);

Complete API Reference

Core Storage Methods

setItem(key: string, value: string, options?: StorageOptions): Promise<boolean>

Stores a key-value pair securely with optional biometric protection and security level specification.

Parameters:

  • key: Unique identifier for the stored value
  • value: Data to store securely
  • options: Optional configuration object

Example:

await SecureStorage.setItem('apiKey', 'sk-123456', {
  withBiometric: true,
  securityLevel: 'hardware', // Android only
  accessControl: ACCESS_CONTROL.BIOMETRY_ANY, // iOS only
});

getItem(key: string, options?: GetItemOptions): Promise<string | null>

Retrieves a stored value, prompting for authentication if required.

removeItem(key: string): Promise<boolean>

Removes a stored key-value pair from secure storage.

hasItem(key: string): Promise<boolean>

Checks if a key exists in storage without retrieving the value.

getAllKeys(): Promise<string[]>

Returns an array of all stored keys.

clear(): Promise<boolean>

Clears all secure storage and removes all encryption keys.

Security & Capability Methods

isBiometricAvailable(): Promise<boolean>

Checks if biometric authentication is available and enrolled on the device.

isHardwareBackedAvailable(): Promise<boolean>

Checks if hardware-backed keystore is available on the current device.

isStrongBoxAvailable(): Promise<boolean>

Checks if StrongBox hardware security module is available (Android only).

getHardwareSecurityInfo(): Promise<HardwareSecurityInfo>

Returns comprehensive information about device security capabilities.

const info = await SecureStorage.getHardwareSecurityInfo();
// {
//   isHardwareBackedAvailable: true,
//   isStrongBoxAvailable: true,
//   recommendedSecurityLevel: 'strongbox'
// }

getPlatformCapabilities(): Promise<PlatformCapabilities>

Returns detailed platform-specific feature availability.

isKeyHardwareBacked(key: string): Promise<boolean>

Checks if a specific stored key uses hardware-backed security.

getKeySecurityLevel(key: string): Promise<string>

Returns the security level of a specific key ('strongbox', 'hardware', 'software', 'unknown').

getRecommendedSecurityLevel(): Promise<'strongbox' | 'hardware' | 'software'>

Returns the recommended security level for the current device.

getSecurityStatus(): Promise<SecurityStatus>

Returns security information for all stored keys.

meetsSecurityRequirements(requirements): Promise<{meets: boolean, missing: string[]}>

Checks if the current device meets specified security requirements.

Platform-Specific Methods

Android Only

setStrongBoxItem(key: string, value: string, allowFallback?: boolean): Promise<boolean>

Convenience method to store data with StrongBox security.

iOS Only

setKeychainItem(key: string, value: string, accessControl?: string, accessGroup?: string): Promise<boolean>

Convenience method for iOS Keychain with custom access control.

Utility Methods

migrateToSecureStorage(key: string, plainValue: string, options?: StorageOptions): Promise<boolean>

Migrates plain text data to secure storage.

isSecurityLevelAvailable(level: 'strongbox' | 'hardware'): Promise<boolean>

Checks if a specific security level is available on the current device.

Type Definitions

StorageOptions

interface StorageOptions {
  withBiometric?: boolean;
  // Android-specific options
  requireStrongBox?: boolean;
  requireHardware?: boolean;
  securityLevel?: 'auto' | 'strongbox' | 'hardware' | 'software';
  allowFallback?: boolean;
  // iOS-specific options
  accessGroup?: string | null;
  accessControl?: string | null;
  // Authentication prompts
  authenticatePrompt?: string;
  authenticatePromptSubtitle?: string;
}

GetItemOptions

interface GetItemOptions {
  // iOS-specific
  accessGroup?: string | null;
  kLocalizedFallbackTitle?: string;
  // Android-specific
  showModal?: boolean;
  // Common
  authenticatePrompt?: string;
  authenticatePromptSubtitle?: string;
}

HardwareSecurityInfo

interface HardwareSecurityInfo {
  isHardwareBackedAvailable: boolean;
  isStrongBoxAvailable: boolean;
  recommendedSecurityLevel: 'strongbox' | 'hardware' | 'software';
}

PlatformCapabilities

interface PlatformCapabilities {
  platform: string;
  hasStrongBox: boolean;
  hasHardwareBackedKeystore: boolean;
  hasBiometrics: boolean;
  hasKeychainAccessControl: boolean;
}

Constants

iOS Access Control

import { ACCESS_CONTROL } from 'rn-secure-keystore';

const ACCESS_CONTROL = {
  BIOMETRY_ANY: 'kSecAccessControlBiometryAny',
  BIOMETRY_CURRENT_SET: 'kSecAccessControlBiometryCurrentSet',
  DEVICE_PASSCODE: 'kSecAccessControlDevicePasscode',
  APPLICATION_PASSWORD: 'kSecAccessControlApplicationPassword',
  BIOMETRY_ANY_OR_DEVICE_PASSCODE:
    'kSecAccessControlBiometryAnyOrDevicePasscode',
};

Error Codes

import { ERROR_CODES } from 'rn-secure-keystore';

// Authentication errors
ERROR_CODES.AUTHENTICATION_CANCELLED;
ERROR_CODES.AUTHENTICATION_FAILED;
ERROR_CODES.BIOMETRIC_NOT_AVAILABLE;

// Platform errors
ERROR_CODES.PLATFORM_NOT_SUPPORTED;
ERROR_CODES.STRONGBOX_NOT_AVAILABLE;

// Storage errors
ERROR_CODES.STORAGE_ERROR;
ERROR_CODES.RETRIEVAL_ERROR;
// ... and more

Error Handling

The library provides comprehensive error handling with detailed error codes:

import { SecureStorageError, ERROR_CODES } from 'rn-secure-keystore';

try {
  await SecureStorage.getItem('protectedKey');
} catch (error) {
  if (error instanceof SecureStorageError) {
    switch (error.code) {
      case ERROR_CODES.AUTHENTICATION_CANCELLED:
        console.log('User cancelled authentication');
        break;
      case ERROR_CODES.BIOMETRIC_NOT_AVAILABLE:
        console.log('Biometric authentication not available');
        break;
      case ERROR_CODES.STRONGBOX_NOT_AVAILABLE:
        console.log('StrongBox not supported on this device');
        break;
      default:
        console.error('Storage error:', error.message);
    }
  }
}

Best Practices

1. Check Capabilities First

const capabilities = await SecureStorage.getPlatformCapabilities();
if (capabilities.hasStrongBox) {
  // Use StrongBox for maximum security
  await SecureStorage.setStrongBoxItem('ultraSecret', 'value');
} else if (capabilities.hasHardwareBackedKeystore) {
  // Fallback to hardware backing
  await SecureStorage.setItem('secret', 'value', { securityLevel: 'hardware' });
}

2. Handle Biometric Availability

const biometricAvailable = await SecureStorage.isBiometricAvailable();
if (biometricAvailable) {
  await SecureStorage.setItem('biometricData', 'secret', {
    withBiometric: true,
  });
} else {
  // Fallback to device passcode or other authentication
  await SecureStorage.setItem('data', 'secret');
}

3. Use Appropriate Security Levels

// For highly sensitive data (credit cards, private keys)
await SecureStorage.setItem('creditCard', cardNumber, {
  securityLevel: 'strongbox',
  withBiometric: true,
  allowFallback: true,
});

// For moderately sensitive data (API tokens)
await SecureStorage.setItem('apiToken', token, {
  securityLevel: 'hardware',
  allowFallback: true,
});

// For less sensitive data (user preferences)
await SecureStorage.setItem('userPrefs', preferences);

4. Implement Proper Error Handling

try {
  const secret = await SecureStorage.getItem('protectedData', {
    authenticatePrompt: 'Access your secure data',
  });
} catch (error) {
  if (error instanceof SecureStorageError) {
    switch (error.code) {
      case ERROR_CODES.AUTHENTICATION_CANCELLED:
        // Don't show error, user intentionally cancelled
        break;
      case ERROR_CODES.AUTHENTICATION_FAILED:
        showRetryDialog();
        break;
      default:
        showGenericErrorDialog(error.message);
    }
  }
}

5. Audit Security Status

const securityStatus = await SecureStorage.getSecurityStatus();
for (const [key, info] of Object.entries(securityStatus)) {
  console.log(
    `${key}: Hardware=${info.isHardwareBacked}, Level=${info.securityLevel}`
  );
}

Platform Differences

Storage Options

| Feature | iOS | Android | Notes | | ----------------- | ------------------------ | ------------------------ | ------------------------------------------------ | | Basic Storage | Hardware-backed keychain | Default Android Keystore | iOS automatically hardware-backed when available | | Hardware Storage | Same as basic | Explicit TEE backing | iOS: automatic, Android: explicit | | StrongBox | Not available | Dedicated security chip | Android-only feature | | Biometric Storage | Face ID/Touch ID | Fingerprint | Platform-native biometric APIs |

Key Differences

iOS:

  • Basic storage = Hardware storage (automatically hardware-backed)
  • Access control determines authentication requirements
  • All keychain items are secure when Secure Enclave is available

Android:

  • Hardware ≠ StrongBox (explicit security levels)
  • Manual security level control
  • StrongBox provides highest security when available

Troubleshooting

Common Issues

"The package doesn't seem to be linked"

  • Run npx pod-install (iOS)
  • Rebuild your app after installation
  • Avoid Expo Go (use development build)

Multiple biometric prompts

  • Use single setItem() call with withBiometric: true
  • Don't call getItem() immediately after setItem() for biometric-protected data

"bad base-64" error (Android)

  • Corrupted EncryptedSharedPreferences data
  • Use clear() method to clean up corrupted storage
  • Library automatically handles fallback to regular SharedPreferences

StrongBox not available

  • StrongBox requires newer Android devices (API 28+)
  • Use allowFallback: true for broader compatibility
  • Check isStrongBoxAvailable() before using

Authentication errors

  • Ensure biometrics are enrolled on device
  • Use clear authenticatePrompt messages
  • Handle user cancellations gracefully

Debug Information

Enable logging to see detailed storage operations:

// Check device capabilities
const info = await SecureStorage.getHardwareSecurityInfo();
console.log('Security capabilities:', info);

// Check individual key security
const keyInfo = await SecureStorage.isKeyHardwareBacked('myKey');
console.log('Key hardware-backed:', keyInfo);

Requirements

  • React Native: 0.60+
  • iOS: 11.0+
  • Android: API level 23+ (Android 6.0+)

Advanced Features

Security Requirements Validation

const requirements = {
  requireBiometric: true,
  requireHardwareBacking: true,
  requireStrongBox: false,
};

const { meets, missing } =
  await SecureStorage.meetsSecurityRequirements(requirements);
if (!meets) {
  console.log('Missing security features:', missing);
}

Migration from Plain Storage

// Migrate existing plain text data to secure storage
await SecureStorage.migrateToSecureStorage('oldKey', plainTextValue, {
  securityLevel: 'hardware',
  withBiometric: true,
});

📄 License

MIT

Contributing

Contributions are welcome! Please open issues and pull requests with clear descriptions.

Support

For issues and questions:

  • GitHub Issues: Report bugs and feature requests
  • Documentation: Check this README for comprehensive API documentation
  • Examples: See the /example folder for complete usage examples

Made with ❤️ for React Native developers who care about security.