Skip to main content

API Reference

Hooks

useKeyPair

Manages an RSA-OAEP key pair lifecycle — generation, import, serialization, and clearing. Keys exist only in React state; serialize to localStorage or IndexedDB for persistence.

function useKeyPair(): UseKeyPairReturn

Returns

PropertyTypeDescription
keyPairCryptoKeyPair | nullThe live key pair after generation or import
serializedSerializedKeyPair | nullBase64-encoded public and private keys, safe to store
generatingbooleantrue while an async operation is running
errorError | nullLast error, or null
generate()() => Promise<void>Generate a new RSA-OAEP 2048-bit key pair
importKeyPair(s)(SerializedKeyPair) => Promise<void>Restore a key pair from a SerializedKeyPair
clear()() => voidReset all state to null

Example

const { keyPair, serialized, generating, error, generate, importKeyPair } = useKeyPair();

// Generate
await generate();

// Persist
localStorage.setItem('kp', JSON.stringify(serialized));

// Restore on next visit
await importKeyPair(JSON.parse(localStorage.getItem('kp')!));

useEncrypt

Encrypts data with an RSA-OAEP public key. Pair with useKeyPair to obtain the public key.

function useEncrypt(options?: UseEncryptOptions): UseEncryptReturn

Options

PropertyTypeDescription
publicKeyCryptoKey | null | undefinedThe RSA public key to encrypt with

Returns

PropertyTypeDescription
encrypt(data)(string | ArrayBuffer) => Promise<string>Encrypt data — returns Base64 ciphertext
encryptingbooleantrue while encrypting
errorError | nullLast error, or null

Example

const { encrypt, encrypting, error } = useEncrypt({ publicKey: keyPair?.publicKey });

const ciphertext = await encrypt('secret message');
// ciphertext is a Base64 string safe to store or transmit
info

encrypt throws if no publicKey is provided. Check that keyPair is populated before calling.


useDecrypt

Decrypts a Base64 RSA-OAEP ciphertext using a private key. Pair with useKeyPair to obtain the private key.

function useDecrypt(options?: UseDecryptOptions): UseDecryptReturn

Options

PropertyTypeDescription
privateKeyCryptoKey | null | undefinedThe RSA private key to decrypt with

Returns

PropertyTypeDescription
decrypt(ciphertext)(string) => Promise<string>Decrypt a Base64 ciphertext — returns plaintext
decryptingbooleantrue while decrypting
errorError | nullLast error, or null

Example

const { decrypt, decrypting, error } = useDecrypt({ privateKey: keyPair?.privateKey });

const plaintext = await decrypt(ciphertext);

useSymmetricKey

Manages an AES-GCM 256-bit symmetric key lifecycle — generation, import, export, encryption, decryption, and clearing.

function useSymmetricKey(): UseSymmetricKeyReturn

Returns

PropertyTypeDescription
keyCryptoKey | nullThe live AES key
exportedKeystring | nullBase64 raw export of the key, safe to store
generatingbooleantrue while an async operation is running
errorError | nullLast error, or null
generate()() => Promise<void>Generate a new 256-bit AES-GCM key
importKey(base64)(string) => Promise<void>Restore a key from a Base64 raw export
encrypt(data)(string | ArrayBuffer) => Promise<string>Encrypt — returns Base64 IV || ciphertext
decrypt(ciphertext)(string) => Promise<string>Decrypt a Base64 IV || ciphertext
clear()() => voidReset all state to null

Example

const { generate, encrypt, decrypt, exportedKey } = useSymmetricKey();

await generate();

const ciphertext = await encrypt('payload');

// Persist the key
localStorage.setItem('aesKey', exportedKey!);

// Restore later
await importKey(localStorage.getItem('aesKey')!);

const plaintext = await decrypt(ciphertext);
IV is automatic

A fresh 96-bit random IV is generated for every encrypt call and prepended to the output. decrypt extracts it automatically — you never need to manage IVs separately.


useKeyStorage

Persists and retrieves an AES-GCM key in IndexedDB identified by a string key. On mount, it automatically checks if a key exists for the given identifier and loads it.

function useKeyStorage(
identifier: string,
options?: UseKeyStorageOptions
): UseKeyStorageReturn

Options

PropertyTypeDefaultDescription
dbNamestring"react-e2ee"IndexedDB database name
storeNamestring"keys"IndexedDB object store name

Returns

PropertyTypeDescription
hasKeyboolean | nullnull while loading; true/false once resolved
loadingbooleantrue during the initial IndexedDB check
errorError | nullLast error, or null
keyCryptoKey | nullThe loaded AES key, or null
saveKey(key)(CryptoKey) => Promise<void>Persist a key to IndexedDB for this identifier
removeKey()() => Promise<void>Delete the key from IndexedDB and clear state

Example

const { hasKey, key, loading, saveKey, removeKey } = useKeyStorage('user-alice');

if (loading) return <p>Checking storage…</p>;
if (!hasKey) return <p>No key saved for this identifier.</p>;
// key is ready to use

useSeedKey

Derives an AES-GCM key from a password + identifier pair using PBKDF2 (600 000 iterations, SHA-256). Internally composes useKeyStorage to cache the derived key in IndexedDB so users don't need to re-enter their password on every visit. Because PBKDF2 derivation is deterministic, the same inputs produce the same key on any device — no synchronization needed.

function useSeedKey(
identifier: string,
options?: UseSeedKeyOptions
): UseSeedKeyReturn

Options

Extends UseKeyStorageOptions with:

PropertyTypeDefaultDescription
dbNamestring"react-e2ee"IndexedDB database name
storeNamestring"keys"IndexedDB object store name
pbkdf2Iterationsnumber600000PBKDF2 iteration count (higher = more secure, slower)

Returns

PropertyTypeDescription
hasKeyboolean | nullnull while loading; true if a cached key exists
keyCryptoKey | nullThe ready-to-use AES key
loadingbooleantrue during mount check
errorError | nullLast error, or null
deriveAndSave(password)(string) => Promise<void>Derive key from password + identifier and cache it
removeKey()() => Promise<void>Delete the cached key from IndexedDB

Example

const { hasKey, key, loading, deriveAndSave, removeKey } = useSeedKey('user-alice');

if (loading) return <p>Checking for saved key…</p>;

if (!hasKey) {
return (
<button onClick={() => deriveAndSave('user-entered-password')}>
Set up encryption
</button>
);
}

// key is available — use aesEncrypt / aesDecrypt from the lib utilities
Cross-device

On a new device, call deriveAndSave with the same password and identifier. The derived key is identical to the one on the original device — any data encrypted there can be decrypted here without transferring the key.


useSecretExchange

Re-encrypts a secret from the sender's AES key to a target user's RSA public key, enabling secure hand-off between users without the server ever seeing the plaintext.

Internally loads the sender's AES-GCM key from IndexedDB (via useKeyStorage) using the given identifier.

function useSecretExchange(
identifier: string,
options?: UseKeyStorageOptions
): UseSecretExchangeReturn

Options

Same as UseKeyStorageOptionsdbName and storeName.

Returns

PropertyTypeDescription
hasKeyboolean | nullnull while loading; true if the sender's key is loaded
loadingbooleantrue during the initial IndexedDB check
errorError | nullLast error, or null
keyCryptoKey | nullThe sender's live AES-GCM key
encryptFor(ciphertext, targetPublicKey)(string, CryptoKey | string) => Promise<string>Decrypt AES ciphertext, re-encrypt for target with RSA
wrapKeyFor(targetPublicKey)(CryptoKey | string) => Promise<string>RSA-wrap the sender's AES key for the target

targetPublicKey accepts either a live CryptoKey or a Base64 SPKI string (the serialized.publicKey from useKeyPair).

encryptFor — single message hand-off

// Sender
const { encryptFor, loading } = useSecretExchange('user-alice');

const envelope = await encryptFor(aliceCiphertext, bobPublicKey);
// Send `envelope` to Bob — e.g. via your API

// Bob — decrypt with his RSA private key
const { decrypt } = useDecrypt({ privateKey: bobKeyPair.privateKey });
const plaintext = await decrypt(envelope);

wrapKeyFor — grant full access

// Sender — share the AES key itself (grants access to ALL messages)
const { wrapKeyFor } = useSecretExchange('user-alice');

const wrappedKey = await wrapKeyFor(bobPublicKey);
// Send `wrappedKey` + any AES ciphertexts to Bob

// Bob — unwrap AES key, then decrypt any ciphertext
const { decrypt: rsaDecrypt } = useDecrypt({ privateKey: bobKeyPair.privateKey });
const rawAesKey = await rsaDecrypt(wrappedKey);
const aesKey = await importAesKey(rawAesKey);
const plaintext = await aesDecrypt(aesKey, aliceCiphertext);
Which method to use?
  • Use encryptFor to share a single specific message securely.
  • Use wrapKeyFor to grant ongoing read access to all past and future messages encrypted with the sender's AES key.

---### useServerKeyPair

Generates an RSA-OAEP key pair whose private key is AES-GCM encrypted for server storage. The AES key is loaded from IndexedDB by identifier (requires useSeedKey to have been called first). The encrypted private key can be safely stored on the server — only the owner can decrypt it client-side.

function useServerKeyPair(
identifier: string,
options?: UseKeyStorageOptions
): UseServerKeyPairReturn

Options

Same as UseKeyStorageOptionsdbName and storeName.

Returns

PropertyTypeDescription
loadingbooleantrue while the owner's AES key is loading from IndexedDB, or while generate / loadPrivateKey is running
errorError | nullLast error, or null
privateKeyCryptoKey | nullThe decrypted RSA private key, available after loadPrivateKey succeeds
generate()() => Promise<ServerKeyPair>Generate a fresh RSA key pair and AES-encrypt the private key — returns { publicKey, encryptedPrivateKey } to upload to your server
loadPrivateKey(encrypted)(string) => Promise<void>Decrypt an encryptedPrivateKey from the server and store it as privateKey

Example

// One-time setup — after useSeedKey has derived and saved the AES key
const { generate, loading } = useServerKeyPair('user-bob');

useEffect(() => {
if (!loading) {
generate().then(({ publicKey, encryptedPrivateKey }) => {
// Upload both to your API
api.saveKeyPair(userId, { publicKey, encryptedPrivateKey });
});
}
}, [loading]);

// Subsequent visits — restore the private key from the server
const { loadPrivateKey, privateKey, loading: kpLoading } = useServerKeyPair('user-bob');

useEffect(() => {
if (!kpLoading) {
api.getKeyPair(userId).then(({ encryptedPrivateKey }) =>
loadPrivateKey(encryptedPrivateKey)
);
}
}, [kpLoading]);

// Once privateKey is set, use rsaDecrypt to open envelopes from senders
How it works

generate() produces a fresh RSA key pair. The private key is exported as PKCS#8, then AES-GCM encrypted using the owner's seed key (from IndexedDB). Only the encrypted blob reaches the server — the server never sees the private key in cleartext.


usePlatformAccess

Attaches a platform emergency-access layer to any AES-encrypted payload without affecting normal end-to-end encryption. The platform publishes an RSA-OAEP public key; usePlatformAccess imports it and exposes two operations:

  • wrapKey — RSA-wrap an existing AES key for the platform.
  • encryptWithAccess — generate a fresh AES key, encrypt data, and simultaneously wrap the key for the platform in one call.

The resulting "platform envelope" is stored alongside the ciphertext. Only the platform's RSA private key can open it.

function usePlatformAccess(
platformPublicKey: CryptoKey | string
): UsePlatformAccessReturn

Parameters

ParameterTypeDescription
platformPublicKeyCryptoKey | stringThe platform's RSA-OAEP public key — a Base64 SPKI string or an already-imported CryptoKey. Re-imports automatically when the value changes.

Returns

PropertyTypeDescription
readybooleantrue once the platform public key is imported and usable
loadingbooleantrue while the key is being imported
errorError | nullImport or encryption error, or null
wrapKey(aesKey)(CryptoKey) => Promise<string>RSA-wrap an existing AES key for the platform — returns the Base64 platform envelope
encryptWithAccess(data)(string | ArrayBuffer) => Promise<PlatformEncryptResult>Generate AES key, encrypt data, and wrap key for the platform — all in one call

PlatformEncryptResult

PropertyTypeDescription
ciphertextstringAES-GCM Base64 ciphertext (IV prepended)
platformEnvelopestringRSA-OAEP Base64 envelope — the AES key wrapped for the platform
aesKeyCryptoKeyThe raw AES key — use it to also wrap for intended recipients
exportedKeystringBase64 raw AES key — importable via importAesKey

Example — wrapping an existing key

const PLATFORM_KEY = 'MIIBIjAN…'; // Base64 SPKI from your app config

function SendMessage() {
const { wrapKey, ready } = usePlatformAccess(PLATFORM_KEY);
const { key, generate, encrypt } = useSymmetricKey();

const handleSend = async () => {
if (!key) return;
const ciphertext = await encrypt('sensitive message');
const platformEnvelope = ready ? await wrapKey(key) : null;
// Persist { ciphertext, platformEnvelope } together
};
}

Example — one-call encrypt + wrap

const PLATFORM_KEY = 'MIIBIjAN…';

function SendMessage({ bobPublicKey }) {
const { encryptWithAccess, ready } = usePlatformAccess(PLATFORM_KEY);
const { encrypt: encryptForBob } = useEncrypt({ publicKey: bobPublicKey });

const handleSend = async () => {
const { ciphertext, platformEnvelope, exportedKey } =
await encryptWithAccess('hello Bob');

// Also wrap the AES key for the intended recipient
const recipientEnvelope = await encryptForBob(exportedKey);

// Persist { ciphertext, platformEnvelope, recipientEnvelope }
};
}
Key management

The platform's private key must be stored securely and never sent to the browser. Treat the public key as a configuration value (e.g. an environment variable or a CDN-hosted JSON config).


useDigest

Computes cryptographic hashes using the Web Crypto API. Supports SHA-1, SHA-256, SHA-384, and SHA-512. Stateless — no key required.

function useDigest(): UseDigestReturn

Returns

PropertyTypeDescription
digest(data, algorithm?)(string | ArrayBuffer, DigestAlgorithm?) => Promise<string>Hash data — returns Base64 digest. Default algorithm: SHA-256.
digestingbooleantrue while hashing
errorError | nullLast error, or null

Example

const { digest, digesting, error } = useDigest();

const sha256 = await digest('Hello, world!');
const sha512 = await digest('Hello, world!', 'SHA-512');
info

DigestAlgorithm is "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512". SHA-1 is included for legacy compatibility but should not be used for new security-sensitive purposes.


useHmac

Manages an HMAC key and provides sign / verify operations for message authentication.

function useHmac(): UseHmacReturn

Returns

PropertyTypeDescription
keyCryptoKey | nullThe live HMAC key
exportedKeystring | nullBase64 raw export of the key
generatingbooleantrue while an async operation is running
errorError | nullLast error, or null
generate(hash?)(HmacHash?) => Promise<void>Generate a new HMAC key. Default hash: SHA-256
importKey(base64, hash?)(string, HmacHash?) => Promise<void>Import a Base64 raw HMAC key
sign(data)(string | ArrayBuffer) => Promise<string>Sign data — returns Base64 signature
verify(signature, data)(string, string | ArrayBuffer) => Promise<boolean>Verify a signature — returns true if valid
clear()() => voidClear the key from state

Example

const { generate, sign, verify, exportedKey } = useHmac();

await generate(); // SHA-256 by default
const sig = await sign('important data');
const ok = await verify(sig, 'important data'); // true

useSign

Manages an ECDSA key pair for digital signatures. Supports P-256, P-384, and P-521 curves. Hash is auto-selected based on the curve (P-256 → SHA-256, P-384 → SHA-384, P-521 → SHA-512).

function useSign(): UseSignReturn

Returns

PropertyTypeDescription
keyPairCryptoKeyPair | nullThe live ECDSA key pair
serializedSerializedKeyPair | nullBase64-encoded public and private keys
generatingbooleantrue while an async operation is running
errorError | nullLast error, or null
generate(curve?)(EcCurve?) => Promise<void>Generate a new ECDSA key pair. Default curve: P-256
importKeyPair(s, curve?)(SerializedKeyPair, EcCurve?) => Promise<void>Import a serialized ECDSA key pair
sign(data)(string | ArrayBuffer) => Promise<string>Sign data — returns Base64 signature
verify(sig, data, publicKey?)(string, string | ArrayBuffer, CryptoKey?) => Promise<boolean>Verify a signature. Uses the hook's public key by default, or pass an explicit one.
clear()() => voidClear the key pair from state

Example

const { generate, sign, verify, serialized } = useSign();

await generate(); // P-256 by default
const sig = await sign('message to authenticate');
const ok = await verify(sig, 'message to authenticate'); // true

// Share serialized.publicKey with others so they can verify your signatures
// Verify with someone else's public key
const valid = await verify(sig, 'message', otherPublicKey);
Sender verification

useSign addresses the missing authentication layer in E2E encryption. Pair it with useKeyPair / useEncrypt to add sender verification: sign the ciphertext before sending, and the recipient verifies with the sender's ECDSA public key before decrypting.


useFingerprint

Computes a human-readable fingerprint of a CryptoKey or Base64-encoded key string. Useful for out-of-band key verification between users (e.g. compare fingerprints over a phone call or QR code).

function useFingerprint(): UseFingerprintReturn

Returns

PropertyTypeDescription
fingerprint(key, algorithm?)(CryptoKey | string, DigestAlgorithm?) => Promise<string>Compute a fingerprint — returns colon-separated uppercase hex (e.g. "AB:CD:EF:01:...")
errorError | nullLast error, or null

Example

const { fingerprint } = useFingerprint();

// From a CryptoKey
const fp = await fingerprint(keyPair.publicKey);
// → "A1:B2:C3:D4:E5:F6:07:..."

// From a Base64 key string
const fp2 = await fingerprint(serialized.publicKey);

Utility Functions

All utilities are exported from the package root and use the browser's native SubtleCrypto API directly.

Encoding

FunctionSignatureDescription
encodeText(text: string) => Uint8ArrayUTF-8 string → Uint8Array
decodeText(buffer: ArrayBuffer) => stringArrayBuffer → UTF-8 string
bufferToBase64(buffer: ArrayBuffer) => stringArrayBuffer → Base64 string
base64ToBuffer(base64: string) => ArrayBufferBase64 string → ArrayBuffer

RSA-OAEP

FunctionSignatureDescription
generateRsaKeyPair() => Promise<CryptoKeyPair>Generate a 2048-bit RSA-OAEP key pair
exportRsaPublicKey(key: CryptoKey) => Promise<string>Export public key as Base64 SPKI
exportRsaPrivateKey(key: CryptoKey) => Promise<string>Export private key as Base64 PKCS8
importRsaPublicKey(base64: string) => Promise<CryptoKey>Import from Base64 SPKI
importRsaPrivateKey(base64: string) => Promise<CryptoKey>Import from Base64 PKCS8
rsaEncrypt(publicKey: CryptoKey, data: string | ArrayBuffer) => Promise<string>Encrypt → Base64 ciphertext
rsaDecrypt(privateKey: CryptoKey, ciphertext: string) => Promise<string>Decrypt Base64 ciphertext → plaintext string
encryptRsaPrivateKey(privateKey: CryptoKey, aesKey: CryptoKey) => Promise<string>AES-GCM encrypt an RSA private key for server storage — returns Base64 ciphertext
decryptRsaPrivateKey(encrypted: string, aesKey: CryptoKey) => Promise<CryptoKey>Decrypt an AES-GCM-wrapped RSA private key — returns an importable CryptoKey

AES-GCM

FunctionSignatureDescription
generateAesKey() => Promise<CryptoKey>Generate a 256-bit AES-GCM key
exportAesKey(key: CryptoKey) => Promise<string>Export as Base64 raw key
importAesKey(base64: string) => Promise<CryptoKey>Import from Base64 raw key
aesEncrypt(key: CryptoKey, data: string | ArrayBuffer) => Promise<string>Encrypt → Base64 IV || ciphertext
aesDecrypt(key: CryptoKey, ciphertext: string) => Promise<string>Decrypt Base64 IV || ciphertext → plaintext

PBKDF2

FunctionSignatureDescription
deriveKeyFromSeed(password: string, identifier: string, iterations?: number) => Promise<CryptoKey>PBKDF2 → AES-GCM key. Same inputs always produce the same key. Identifier is SHA-256 hashed to form the salt.

Hashing / Digest

FunctionSignatureDescription
digest(data: string | ArrayBuffer, algorithm?: DigestAlgorithm) => Promise<string>Compute a SHA hash — returns Base64 digest
bufferToHex(buffer: ArrayBuffer) => stringEncode an ArrayBuffer as a lowercase hex string
fingerprint(key: CryptoKey | string, algorithm?: DigestAlgorithm) => Promise<string>Compute a key fingerprint — returns colon-separated uppercase hex

HMAC

FunctionSignatureDescription
generateHmacKey(hash?: HmacHash) => Promise<CryptoKey>Generate an HMAC key
exportHmacKey(key: CryptoKey) => Promise<string>Export as Base64 raw key
importHmacKey(base64: string, hash?: HmacHash) => Promise<CryptoKey>Import from Base64 raw key
hmacSign(key: CryptoKey, data: string | ArrayBuffer) => Promise<string>Sign data — returns Base64 signature
hmacVerify(key: CryptoKey, signature: string, data: string | ArrayBuffer) => Promise<boolean>Verify a signature — returns true if valid

ECDSA

FunctionSignatureDescription
generateEcdsaKeyPair(curve?: EcCurve) => Promise<CryptoKeyPair>Generate an ECDSA key pair
exportEcdsaPublicKey(key: CryptoKey) => Promise<string>Export public key as Base64 SPKI
exportEcdsaPrivateKey(key: CryptoKey) => Promise<string>Export private key as Base64 PKCS8
importEcdsaPublicKey(base64: string, curve?: EcCurve) => Promise<CryptoKey>Import from Base64 SPKI
importEcdsaPrivateKey(base64: string, curve?: EcCurve) => Promise<CryptoKey>Import from Base64 PKCS8
ecdsaSign(privateKey: CryptoKey, data: string | ArrayBuffer) => Promise<string>Sign data — returns Base64 signature
ecdsaVerify(publicKey: CryptoKey, signature: string, data: string | ArrayBuffer) => Promise<boolean>Verify a signature — returns true if valid

TypeScript Types

All types are exported from the package root.

import type {
KeyPairAlgorithm,
SymmetricAlgorithm,
SerializedKeyPair,
UseKeyPairState,
UseKeyPairActions,
UseKeyPairReturn,
UseEncryptOptions,
UseEncryptReturn,
UseDecryptOptions,
UseDecryptReturn,
UseSymmetricKeyReturn,
StoredKeyEntry,
UseKeyStorageOptions,
UseKeyStorageReturn,
UseSeedKeyOptions,
UseSeedKeyReturn,
UseSecretExchangeReturn,
ServerKeyPair,
UseServerKeyPairReturn,
PlatformEncryptResult,
UsePlatformAccessReturn,
DigestAlgorithm,
HmacHash,
EcCurve,
UseDigestReturn,
UseHmacReturn,
UseSignReturn,
UseFingerprintReturn,
} from 'react-e2ee';

KeyPairAlgorithm

type KeyPairAlgorithm = "RSA-OAEP" | "ECDH";
note

Only "RSA-OAEP" is currently implemented. "ECDH" is defined in the type but is not used by any hook or utility function.

SymmetricAlgorithm

type SymmetricAlgorithm = "AES-GCM" | "AES-CBC";
note

Only "AES-GCM" is currently implemented. "AES-CBC" is defined in the type but is not used by any hook or utility function.

SerializedKeyPair

Serialized form of an RSA key pair — both values are Base64 strings safe to store in localStorage or IndexedDB.

interface SerializedKeyPair {
publicKey: string; // Base64 SPKI
privateKey: string; // Base64 PKCS8
}

UseKeyPairReturn

type UseKeyPairReturn = {
keyPair: CryptoKeyPair | null;
serialized: SerializedKeyPair | null;
generating: boolean;
error: Error | null;
generate: () => Promise<void>;
importKeyPair: (serialized: SerializedKeyPair) => Promise<void>;
clear: () => void;
};

UseEncryptReturn

interface UseEncryptReturn {
encrypt: (data: string | ArrayBuffer) => Promise<string>;
encrypting: boolean;
error: Error | null;
}

UseDecryptReturn

interface UseDecryptReturn {
decrypt: (ciphertext: string) => Promise<string>;
decrypting: boolean;
error: Error | null;
}

UseSymmetricKeyReturn

interface UseSymmetricKeyReturn {
key: CryptoKey | null;
exportedKey: string | null;
generating: boolean;
error: Error | null;
generate: () => Promise<void>;
importKey: (base64Key: string) => Promise<void>;
encrypt: (data: string | ArrayBuffer) => Promise<string>;
decrypt: (ciphertext: string) => Promise<string>;
clear: () => void;
}

StoredKeyEntry

interface StoredKeyEntry {
identifier: string;
exportedKey: string; // Base64 AES-GCM raw key
algorithm: 'AES-GCM';
createdAt: number; // Unix timestamp (ms)
}

UseKeyStorageOptions

interface UseKeyStorageOptions {
dbName?: string; // Default: "react-e2ee"
storeName?: string; // Default: "keys"
}

UseKeyStorageReturn

interface UseKeyStorageReturn {
hasKey: boolean | null;
loading: boolean;
error: Error | null;
key: CryptoKey | null;
saveKey: (key: CryptoKey) => Promise<void>;
removeKey: () => Promise<void>;
}

UseSeedKeyOptions

interface UseSeedKeyOptions extends UseKeyStorageOptions {
pbkdf2Iterations?: number; // Default: 600000
}

UseSeedKeyReturn

interface UseSeedKeyReturn {
hasKey: boolean | null;
key: CryptoKey | null;
loading: boolean;
error: Error | null;
deriveAndSave: (password: string) => Promise<void>;
removeKey: () => Promise<void>;
}

UseSecretExchangeReturn

interface UseSecretExchangeReturn {
hasKey: boolean | null;
loading: boolean;
error: Error | null;
key: CryptoKey | null;
encryptFor: (ciphertext: string, targetPublicKey: CryptoKey | string) => Promise<string>;
wrapKeyFor: (targetPublicKey: CryptoKey | string) => Promise<string>;
}

ServerKeyPair

The object returned by useServerKeyPair().generate(). Upload both fields to your server.

interface ServerKeyPair {
publicKey: string; // Base64 SPKI — safe to share publicly
encryptedPrivateKey: string; // AES-GCM ciphertext of the PKCS#8 private key
}

UseServerKeyPairReturn

interface UseServerKeyPairReturn {
loading: boolean;
error: Error | null;
privateKey: CryptoKey | null;
generate: () => Promise<ServerKeyPair>;
loadPrivateKey: (encryptedPrivateKey: string) => Promise<void>;
}

PlatformEncryptResult

interface PlatformEncryptResult {
ciphertext: string; // AES-GCM Base64 ciphertext (IV prepended)
platformEnvelope: string; // RSA-OAEP Base64 wrapped AES key for the platform
aesKey: CryptoKey; // Raw AES key — wrap for other recipients
exportedKey: string; // Base64 raw AES key — importable via importAesKey()
}

UsePlatformAccessReturn

interface UsePlatformAccessReturn {
ready: boolean;
loading: boolean;
error: Error | null;
wrapKey: (aesKey: CryptoKey) => Promise<string>;
encryptWithAccess: (data: string | ArrayBuffer) => Promise<PlatformEncryptResult>;
}

DigestAlgorithm

type DigestAlgorithm = "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512";

HmacHash

type HmacHash = "SHA-256" | "SHA-384" | "SHA-512";

EcCurve

type EcCurve = "P-256" | "P-384" | "P-521";

UseDigestReturn

interface UseDigestReturn {
digest: (data: string | ArrayBuffer, algorithm?: DigestAlgorithm) => Promise<string>;
digesting: boolean;
error: Error | null;
}

UseHmacReturn

interface UseHmacReturn {
key: CryptoKey | null;
exportedKey: string | null;
generating: boolean;
error: Error | null;
generate: (hash?: HmacHash) => Promise<void>;
importKey: (base64Key: string, hash?: HmacHash) => Promise<void>;
sign: (data: string | ArrayBuffer) => Promise<string>;
verify: (signature: string, data: string | ArrayBuffer) => Promise<boolean>;
clear: () => void;
}

UseSignReturn

interface UseSignReturn {
keyPair: CryptoKeyPair | null;
serialized: SerializedKeyPair | null;
generating: boolean;
error: Error | null;
generate: (curve?: EcCurve) => Promise<void>;
importKeyPair: (s: SerializedKeyPair, curve?: EcCurve) => Promise<void>;
sign: (data: string | ArrayBuffer) => Promise<string>;
verify: (sig: string, data: string | ArrayBuffer, publicKey?: CryptoKey) => Promise<boolean>;
clear: () => void;
}

UseFingerprintReturn

interface UseFingerprintReturn {
fingerprint: (key: CryptoKey | string, algorithm?: DigestAlgorithm) => Promise<string>;
error: Error | null;
}