react-e2ee
v0.3.0
Published
Headless React hooks and utilities for client-side end-to-end encryption using the Web Crypto API
Maintainers
Readme
react-e2ee
Headless React hooks for client-side end-to-end encryption using the native Web Crypto API.
Features
- Zero dependencies — built entirely on the browser's
SubtleCryptoAPI. - Headless — pure hooks & utilities, no UI imposed on you.
- RSA-OAEP asymmetric encryption for key exchange and small payloads.
- AES-GCM symmetric encryption for large payloads (with random IV per call).
- ECDSA digital signatures (P-256, P-384, P-521).
- HMAC message authentication (SHA-256 / SHA-384 / SHA-512).
- SHA hashing — SHA-1, SHA-256, SHA-384, SHA-512 digest utilities.
- Key fingerprinting — human-readable colon-separated hex fingerprints.
- TypeScript-first — full type definitions included.
- Secure context — works in HTTPS and
localhostenvironments.
Installation
npm install react-e2ee
# or
pnpm add react-e2ee
# or
yarn add react-e2eeRequires React 18+ and a browser with
SubtleCryptosupport (all modern browsers).
Quick Start
Asymmetric (RSA-OAEP)
import { useKeyPair, useEncrypt, useDecrypt } from "react-e2ee";
function Demo() {
const { keyPair, generating, generate, serialized } = useKeyPair();
const { encrypt, encrypting } = useEncrypt({ publicKey: keyPair?.publicKey });
const { decrypt, decrypting } = useDecrypt({ privateKey: keyPair?.privateKey });
const run = async () => {
await generate();
const ciphertext = await encrypt("Hello, E2E world!");
const plaintext = await decrypt(ciphertext);
console.log(plaintext); // "Hello, E2E world!"
};
return <button onClick={run} disabled={generating}>Run demo</button>;
}Symmetric (AES-GCM)
import { useSymmetricKey } from "react-e2ee";
function SymDemo() {
const { generate, encrypt, decrypt, exportedKey } = useSymmetricKey();
const run = async () => {
await generate();
const ciphertext = await encrypt("Large payload...");
const plaintext = await decrypt(ciphertext);
console.log(plaintext);
};
return <button onClick={run}>Run symmetric demo</button>;
}API
useKeyPair()
Manages an RSA-OAEP key pair.
| Property / Method | Type | Description |
|---|---|---|
| keyPair | CryptoKeyPair \| null | The native key pair |
| serialized | SerializedKeyPair \| null | Base64-encoded public + private key |
| generating | boolean | True while generating or importing |
| error | Error \| null | Last error |
| generate() | () => Promise<void> | Generate a new key pair |
| importKeyPair(s) | (s: SerializedKeyPair) => Promise<void> | Re-import a saved key pair |
| clear() | () => void | Clear state |
useEncrypt({ publicKey })
Encrypt data with an RSA-OAEP public key.
| Property | Type | Description |
|---|---|---|
| encrypt(data) | (data: string \| ArrayBuffer) => Promise<string> | Returns Base64 ciphertext |
| encrypting | boolean | True while encrypting |
| error | Error \| null | Last error |
useDecrypt({ privateKey })
Decrypt data with an RSA-OAEP private key.
| Property | Type | Description |
|---|---|---|
| decrypt(ciphertext) | (ciphertext: string) => Promise<string> | Returns plaintext |
| decrypting | boolean | True while decrypting |
| error | Error \| null | Last error |
useSymmetricKey()
Manages an AES-GCM 256-bit symmetric key.
| Property / Method | Type | Description |
|---|---|---|
| key | CryptoKey \| null | The native key |
| exportedKey | string \| null | Base64 raw key for storage |
| generating | boolean | True while generating or importing |
| error | Error \| null | Last error |
| generate() | () => Promise<void> | Generate a new key |
| importKey(base64) | (base64: string) => Promise<void> | Import a stored key |
| encrypt(data) | (data: string \| ArrayBuffer) => Promise<string> | AES-GCM encrypt (IV prepended) |
| decrypt(ciphertext) | (ciphertext: string) => Promise<string> | AES-GCM decrypt |
| clear() | () => void | Clear state |
useDigest()
Stateless SHA hashing.
| Property / Method | Type | Description |
|---|---|---|
| hash(algorithm, data) | (alg: DigestAlgorithm, data: string \| ArrayBuffer) => Promise<string> | Returns hex digest |
| hashing | boolean | True while hashing |
| error | Error \| null | Last error |
useHmac(hash?)
HMAC key management and message authentication.
| Property / Method | Type | Description |
|---|---|---|
| key | CryptoKey \| null | The native HMAC key |
| exportedKey | string \| null | Base64-encoded raw key |
| generating | boolean | True while generating or importing |
| error | Error \| null | Last error |
| generate() | () => Promise<void> | Generate a new HMAC key |
| importKey(base64) | (base64: string) => Promise<void> | Import a stored key |
| sign(data) | (data: string \| ArrayBuffer) => Promise<string> | Returns Base64 signature |
| verify(signature, data) | (sig: string, data: string \| ArrayBuffer) => Promise<boolean> | Verify a signature |
| clear() | () => void | Clear state |
useSign(curve?)
ECDSA key pair management and digital signatures (default P-256).
| Property / Method | Type | Description |
|---|---|---|
| keyPair | CryptoKeyPair \| null | The native ECDSA key pair |
| serialized | { publicKey: string; privateKey: string } \| null | Base64-encoded keys |
| generating | boolean | True while generating or importing |
| error | Error \| null | Last error |
| generate() | () => Promise<void> | Generate a new ECDSA key pair |
| importKeyPair(s) | (s: { publicKey: string; privateKey: string }) => Promise<void> | Re-import saved keys |
| sign(data) | (data: string \| ArrayBuffer) => Promise<string> | Returns Base64 signature |
| verify(signature, data, publicKey?) | (sig: string, data: string \| ArrayBuffer, pk?: CryptoKey) => Promise<boolean> | Verify with own or external key |
| clear() | () => void | Clear state |
useFingerprint(algorithm?)
Key fingerprinting (default SHA-256).
| Property / Method | Type | Description |
|---|---|---|
| fingerprint(keyBase64) | (key: string) => Promise<string> | Returns colon-separated hex fingerprint |
| computing | boolean | True while computing |
| error | Error \| null | Last error |
Utility Functions
Low-level helpers are also exported for custom use:
import {
// RSA
generateRsaKeyPair, exportRsaPublicKey, exportRsaPrivateKey,
importRsaPublicKey, importRsaPrivateKey,
rsaEncrypt, rsaDecrypt,
// AES
generateAesKey, exportAesKey, importAesKey,
aesEncrypt, aesDecrypt,
// Hashing & Fingerprint
digest, fingerprint, bufferToHex,
// HMAC
generateHmacKey, exportHmacKey, importHmacKey,
hmacSign, hmacVerify,
// ECDSA
generateEcdsaKeyPair, exportEcdsaPublicKey, exportEcdsaPrivateKey,
importEcdsaPublicKey, importEcdsaPrivateKey,
ecdsaSign, ecdsaVerify,
// Encoding
bufferToBase64, base64ToBuffer, encodeText, decodeText,
} from "react-e2ee";Security Notes
- Keys are generated and never leave the browser unless you explicitly serialize and transmit them.
- Uses RSA-OAEP with 2048-bit keys and SHA-256 for asymmetric operations.
- Uses AES-GCM with 256-bit keys and a random 96-bit IV per message for symmetric operations.
- Uses ECDSA (P-256 / P-384 / P-521) for digital signatures with automatic hash selection.
- Uses HMAC (SHA-256 / SHA-384 / SHA-512) for message authentication codes.
- Only works in secure contexts (HTTPS or
localhost). - Private keys should be stored securely (e.g., encrypted storage, HSM) — never in plain
localStoragewithout additional protection.
License
MIT © HorizonDen
