Skip to main content

react-e2ee

react-e2ee provides headless React hooks and low-level utilities for client-side end-to-end encryption using the browser's native Web Crypto API.

  • Zero runtime dependencies — only React as a peer dependency
  • Every cryptographic operation runs entirely in the browser
  • No key ever leaves the client's device
  • Fully typed with TypeScript

What it does

FeatureHook / APIStatus
RSA-OAEP key pair lifecycleuseKeyPair✅ Available
RSA-OAEP encryptionuseEncrypt✅ Available
RSA-OAEP decryptionuseDecrypt✅ Available
AES-GCM symmetric key lifecycleuseSymmetricKey✅ Available
IndexedDB key storage by identifieruseKeyStorage✅ Available
Password → AES key (cross-device, PBKDF2)useSeedKey✅ Available
Platform public key for emergency accessusePlatformAccess✅ Available
Cryptographic hashing (SHA family)useDigest✅ Available
HMAC message authenticationuseHmac✅ Available
ECDSA digital signaturesuseSign✅ Available
Key fingerprintinguseFingerprint✅ Available
RSA key pair with server-stored encrypted private keyuseServerKeyPair✅ Available

How it works

Asymmetric (RSA-OAEP)

A key pair is generated in the browser. The public key can be safely shared — it is used to encrypt data. Only the holder of the private key can decrypt it. This is the classic E2E model used by chat apps and secure messaging protocols.

Sender               Receiver
────── ────────
publicKey ─────────▶ encrypt(data)


ciphertext ──▶ privateKey ─▶ decrypt ─▶ plaintext

Symmetric (AES-GCM)

A single key is used for both encryption and decryption. AES-GCM is faster and supports larger payloads than RSA. Commonly used in hybrid patterns: RSA encrypts the AES key, AES encrypts the data.

Cross-device (PBKDF2)

useSeedKey derives the same AES-GCM key from a password and identifier using PBKDF2. Because the derivation is deterministic, the exact same key is produced on any device given the same inputs — no key synchronization required.

Device A                        Device B
──────── ────────
password + identifier password + identifier
│ │
PBKDF2 PBKDF2
│ │
AES key ◀──────────────────▶ AES key (identical)

Requirements

RequirementDetails
React18 or 19 (peer dependency)
BrowserChrome 37+, Firefox 34+, Safari 11+, Edge 79+
Secure contextHTTPS or localhost — SubtleCrypto is unavailable on plain HTTP
Node.js≥ 18 (library build tooling; SSR environments must polyfill Web Crypto)
Secure context required

The Web Crypto API (SubtleCrypto) is only available in secure contexts. Your app must be served over HTTPS in production. During development, localhost is automatically treated as secure by the browser.


Algorithms

AlgorithmKey sizeUse case
RSA-OAEP2048-bit, SHA-256Asymmetric encryption of small payloads
AES-GCM256-bit, 96-bit IVSymmetric encryption of any payload size
PBKDF2SHA-256, 600 000 iterations (OWASP 2024)Key derivation from a password — used by useSeedKey
HMACSHA-256/384/512Keyed message authentication — used by useHmac
ECDSAP-256 / P-384 / P-521Digital signatures — used by useSign
SHA-256/384/512N/ACryptographic hashing — used by useDigest, useFingerprint

Emergency access

usePlatformAccess lets you attach an optional platform layer to any encrypted payload — without breaking normal end-to-end confidentiality. The platform holds an RSA key pair; its public key is embedded in the app config. Whenever a user encrypts data, the AES key is also RSA-wrapped for the platform and stored as a "platform envelope" next to the ciphertext. In an emergency, the platform decrypts the envelope with its private key to recover the AES key.

User encrypts
─────────────
aesKey ──▶ aesEncrypt(data) ──▶ ciphertext
aesKey ──▶ rsaEncrypt(platformPublicKey, exportedAesKey) ──▶ platformEnvelope

Store { ciphertext, platformEnvelope } together

Emergency access (platform only)
─────────────────────────────────
rsaDecrypt(platformPrivateKey, platformEnvelope) ──▶ exportedAesKey
importAesKey(exportedAesKey) ──▶ aesKey
aesDecrypt(aesKey, ciphertext) ──▶ plaintext

Next steps