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

expo-device-crypto

v1.0.0

Published

Crypto for Expo using device hardware capabilities

Readme

expo-device-crypto

🔒 Hardware-backed cryptography for Expo apps using Android Keystore/Strong Box and Apple Secure Enclave/Keychain.

Installation

npx expo install expo-device-crypto

If you want to allow Face ID on iOS, add this to your app config:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSFaceIDUsageDescription": "We use Face ID to protect your cryptographic keys."
      }
    }
  }
}

Supported Algorithms

✍️ Signature Algorithms

  • ECDSA_SECP256R1_SHA256

    Curve: P-256 / secp256r1. Hash: SHA-256.

  • RSA_SHA256

    Key size: 2048 bits. Padding: PKCS#1 v1.5. Hash: SHA-256.

  • RSA_SHA256_PSS

    Key size: 2048 bits. Padding: RSA-PSS (MGF1). Hash: SHA-256.

🔐 Encryption Algorithms

  • RSA_2048_PKCS1

    Key size: 2048 bits. Padding: PKCS#1 v1.5.

  • RSA_2048_OAEP_SHA1

    Key size: 2048 bits. Padding: OAEP with SHA-1 and MGF1.

  • ECIES_P256_AES256_GCM

    Curve: P-256 (secp256r1). Symmetric cipher: AES-256-GCM. Key derivation: HKDF-SHA256 (32-byte key from ECDH shared secret).

More coming soon...

Example

RSA with Biometric

import DeviceCrypto, {
  AuthCheckResult,
  AuthMethod,
  EncryptionAlgorithm,
} from "expo-device-crypto";

const alias = "user-encryption-key";
const dataToEncrypt = "Sensitive data";
const algorithmType = EncryptionAlgorithm.RSA_2048_PKCS1;
const authMethod = AuthMethod.PASSCODE_OR_BIOMETRIC;

// 1) Ensure device authentication is configured (passcode at minimum)
const authStatus = DeviceCrypto.isAuthCheckAvailable();
if (authStatus !== AuthCheckResult.AVAILABLE) {
  throw new Error(`Authentication unavailable: ${authStatus}`);
}

// 2) Generate an auth-protected RSA key pair
await DeviceCrypto.generateKeyPair(alias, {
  algorithmType,
  requireAuthentication: true,
  authMethod, // iOS: defined at key generation;
});

// 3) Optional: retrieve/share public key with backend
const publicKeyPem = DeviceCrypto.getPublicKey(alias);

// 4) Encrypt with public key
const encrypted = await DeviceCrypto.encrypt(alias, dataToEncrypt, {
  algorithmType,
});

// 5) Decrypt with private key
// Note: Data to decrypt must be in Base64 format.
// Note: This function should display the system user authentication prompt.
const decrypted = await DeviceCrypto.decrypt(alias, encrypted, {
  algorithmType,
  authMethod, // Android: defined when decrypting
});

⚠️ Because iOS Keychain/Secure Enclave binds authentication policy to key creation, authMethod must be set in generateKeyPair. On Android Keystore, authentication is applied at key usage time, so authMethod is provided in operations like sign and decrypt.

📚 More examples

You can find additional usage examples in the examples directory of the main repository.

Methods

  • isAuthCheckAvailable(): AuthCheckResult

    • Returns device authentication availability (AVAILABLE, NO_HARDWARE, UNAVAILABLE).
  • generateKeyPair(alias: string, options?: GenerateKeyPairOptions): Promise<GenerateKeyPairResult>

    • Creates a key pair for alias if it does not exist.
    • Defaults: requireAuthentication = false, authMethod = PASSCODE_OR_BIOMETRIC.
  • getPublicKey(alias: string, options?: GetPublicKeyOptions): string | null

    • Returns public key in PEM format (or null if alias not found).
    • Defaults: format = "PEM".
  • removeKeyPair(alias: string): boolean

    • Removes the key pair for the alias.
  • aliases(): string[]

    • Lists stored key aliases.
  • sign(alias: string, data: string, options?: SignOptions): Promise<string | null>

    • Signs UTF-8 data with private key.
    • Defaults: algorithmType = ECDSA_SECP256R1_SHA256, promptTitle = "Unlock", promptSubtitle = "Enter your PIN to continue", authMethod = PASSCODE_OR_BIOMETRIC.
  • verify(alias: string, data: string, signature: string, options?: VerifyOptions): Promise<boolean | null>

    • Verifies signature for UTF-8 data.
    • Signature must be in Base64 format.
    • Default: algorithmType = ECDSA_SECP256R1_SHA256.
  • encrypt(alias: string, data: string, options?: EncryptOptions): Promise<string | null>

    • Encrypts UTF-8 data with public key.
    • Default: algorithmType = RSA_2048_PKCS1.
    • For algorithmType = ECIES_P256_AES256_GCM, peerPublicKey is required in options.
  • decrypt(alias: string, data: string, options?: DecryptOptions): Promise<string | null>

    • Decrypts Base64 data with private key.
    • Defaults: algorithmType = RSA_2048_PKCS1, promptTitle = "Unlock", promptSubtitle = "Enter your PIN to continue", authMethod = PASSCODE_OR_BIOMETRIC.
    • For algorithmType = ECIES_P256_AES256_GCM, peerPublicKey is required in options.

Android only methods

  • isStrongBoxAvailable(): boolean
    • Returns true if StrongBox Keystore is supported on the device.

Important

Enable Strong Box on Android

Use preferStrongBox: true when generating a key pair to request StrongBox-backed key storage when the device supports it.

import DeviceCrypto, { SigningAlgorithm } from "expo-device-crypto";

const alias = "user-signing-key";

// Optional: check availability first.
const hasStrongBox = DeviceCrypto.isStrongBoxAvailable();

await DeviceCrypto.generateKeyPair(alias, {
  algorithmType: SigningAlgorithm.ECDSA_SECP256R1_SHA256,
  preferStrongBox: true,
});

If StrongBox is not available, Android falls back to the Trusted Execution Environment (TEE).

Secure Enclave support on iOS

On iOS, only ECDSA keys can use the Secure Enclave processor. RSA private-key operations are software-backed and handled by Apple’s system cryptographic services, which still provide strong isolation and protection.

ECIES - EC encryption schema

For library purposes, ECIES is referred to as an encryption algorithm for simplification, even though it is technically a broader encryption scheme.