zerokey
Version:
Zero-knowledge cross-domain secret sharing library using ECDH encryption
212 lines (209 loc) • 9.16 kB
text/typescript
export { clearSecret, getSecret, initSecretClient } from './client.cjs';
export { initSecretServer, setSecret } from './server.cjs';
/**
* Represents an asymmetric cryptographic key pair for ECDH operations.
*
* @interface KeyPair
* @property {string} publicKey - The public key encoded as a base64url string.
* This key can be safely shared with others.
* @property {CryptoKey} privateKey - The private key as a native CryptoKey object.
* This key must be kept secret and never shared.
*
* @example
* ```typescript
* const keyPair = await generateKeyPair();
* console.log(keyPair.publicKey); // Safe to share
* // keyPair.privateKey is kept secret
* ```
*/
interface KeyPair {
publicKey: string;
privateKey: CryptoKey;
}
/**
* Generates a new ECDH (Elliptic Curve Diffie-Hellman) key pair using the P-256 curve.
*
* This function creates a cryptographically secure key pair suitable for key exchange
* and hybrid encryption operations. The P-256 curve (also known as secp256r1) provides
* 128-bit security strength.
*
* @returns {Promise<KeyPair>} A promise that resolves to a KeyPair object containing
* the public key (as base64url string) and private key (as CryptoKey).
*
* @throws {Error} Throws if the Web Crypto API is not available or key generation fails.
*
* @example
* ```typescript
* const keyPair = await generateKeyPair();
* // Store keyPair.publicKey in database or share with others
* // Keep keyPair.privateKey secure and never transmit it
* ```
*
* @see {@link https://www.w3.org/TR/WebCryptoAPI/#ecdh|W3C Web Crypto API ECDH}
*/
declare function generateKeyPair(): Promise<KeyPair>;
/**
* Exports a CryptoKey public key to a base64url-encoded string format.
*
* This function converts a native CryptoKey object to a portable string format
* that can be safely transmitted over networks, stored in databases, or shared
* between different systems. The base64url encoding is URL-safe and doesn't
* require additional encoding.
*
* @param {CryptoKey} publicKey - The public key to export. Must be an ECDH P-256 public key.
*
* @returns {Promise<string>} A promise that resolves to the base64url-encoded public key.
*
* @throws {Error} Throws if the key export fails or if the provided key is not a valid public key.
*
* @example
* ```typescript
* const keyPair = await generateKeyPair();
* const publicKeyString = await exportPublicKey(keyPair.publicKey);
* // publicKeyString can now be stored or transmitted
* ```
*/
declare function exportPublicKey(publicKey: CryptoKey): Promise<string>;
/**
* Imports a public key from a base64url-encoded string to a CryptoKey object.
*
* This function converts a portable string representation of a public key back
* into a native CryptoKey object that can be used for cryptographic operations.
* The key must be a valid ECDH P-256 public key in raw format.
*
* @param {string} publicKeyString - The base64url-encoded public key string to import.
*
* @returns {Promise<CryptoKey>} A promise that resolves to the imported public key as a CryptoKey object.
*
* @throws {Error} Throws if the string is not a valid base64url-encoded key or if import fails.
*
* @example
* ```typescript
* const publicKeyString = "your-base64url-encoded-public-key";
* const publicKey = await importPublicKey(publicKeyString);
* // publicKey can now be used for encryption operations
* ```
*/
declare function importPublicKey(publicKeyString: string): Promise<CryptoKey>;
/**
* Serializes a private key to a JSON string for secure storage.
*
* This function exports a private key in JWK (JSON Web Key) format, which preserves
* all key parameters and can be safely stored in secure storage systems. The resulting
* string contains sensitive key material and must be protected accordingly.
*
* @param {CryptoKey} privateKey - The private key to serialize. Must be an ECDH P-256 private key.
*
* @returns {Promise<string>} A promise that resolves to the JSON-serialized private key.
*
* @throws {Error} Throws if the key export fails or if the provided key is not extractable.
*
* @example
* ```typescript
* const keyPair = await generateKeyPair();
* const serialized = await serializePrivateKey(keyPair.privateKey);
* // Store 'serialized' in secure storage (e.g., encrypted database, secure keychain)
* ```
*
* @security This function returns sensitive key material. Ensure the output is stored
* securely and never transmitted over insecure channels.
*/
declare function serializePrivateKey(privateKey: CryptoKey): Promise<string>;
/**
* Deserializes a private key from a JSON string back to a CryptoKey object.
*
* This function imports a private key that was previously serialized using
* serializePrivateKey(). It restores the key to a usable CryptoKey object
* for cryptographic operations.
*
* @param {string} privateKeyString - The JSON-serialized private key string to deserialize.
*
* @returns {Promise<CryptoKey>} A promise that resolves to the imported private key as a CryptoKey object.
*
* @throws {Error} Throws if the string is not valid JSON or contains an invalid JWK structure.
*
* @example
* ```typescript
* // Retrieve serialized key from secure storage
* const serialized = await getFromSecureStorage('privateKey');
* const privateKey = await deserializePrivateKey(serialized);
* // privateKey can now be used for decryption operations
* ```
*
* @security Handle the input string with care as it contains sensitive key material.
*/
declare function deserializePrivateKey(privateKeyString: string): Promise<CryptoKey>;
/**
* Encrypts a secret using hybrid encryption (ECDH + AES-GCM).
*
* This function implements a hybrid encryption scheme that combines the security of
* asymmetric encryption with the efficiency of symmetric encryption. It generates
* an ephemeral key pair, derives a shared secret using ECDH, and then encrypts
* the data using AES-GCM with the derived key.
*
* The encryption process:
* 1. Generates an ephemeral ECDH key pair
* 2. Derives a shared AES key using ECDH with the recipient's public key
* 3. Encrypts the secret using AES-GCM
* 4. Packages the ephemeral public key with the encrypted data
*
* @param {string} secret - The secret data to encrypt. Can be any string value.
* @param {string} publicKeyString - The recipient's public key as a base64url-encoded string.
*
* @returns {Promise<string>} A promise that resolves to a base64url-encoded encrypted payload
* containing both the ephemeral public key and encrypted data.
*
* @throws {Error} Throws if encryption fails or if the public key is invalid.
*
* @example
* ```typescript
* const recipientPublicKey = "their-public-key-string";
* const secretMessage = "This is a secret message";
*
* const encrypted = await encryptWithPublicKey(secretMessage, recipientPublicKey);
* // 'encrypted' can be safely transmitted to the recipient
* // Only the holder of the corresponding private key can decrypt it
* ```
*
* @see {@link decryptWithPrivateKey} for the corresponding decryption function
*/
declare function encryptWithPublicKey(secret: string, publicKeyString: string): Promise<string>;
/**
* Decrypts data that was encrypted using hybrid encryption (ECDH + AES-GCM).
*
* This function reverses the encryption performed by encryptWithPublicKey().
* It extracts the ephemeral public key from the encrypted payload, derives
* the same shared secret using ECDH, and then decrypts the data using AES-GCM.
*
* The decryption process:
* 1. Extracts the ephemeral public key from the encrypted payload
* 2. Derives the shared AES key using ECDH with the private key
* 3. Decrypts the data using AES-GCM with the derived key
*
* @param {string} encryptedString - The base64url-encoded encrypted payload containing
* the ephemeral public key and encrypted data.
* @param {CryptoKey} privateKey - The recipient's private key for decryption.
*
* @returns {Promise<string>} A promise that resolves to the decrypted secret string.
*
* @throws {Error} Throws "Failed to decrypt secret" if decryption fails for any reason,
* including invalid encrypted data, wrong private key, or corrupted payload.
*
* @example
* ```typescript
* const keyPair = await generateKeyPair();
* // Receive encrypted message from sender
* const encryptedMessage = "encrypted-payload-from-sender";
*
* try {
* const decrypted = await decryptWithPrivateKey(encryptedMessage, keyPair.privateKey);
* console.log("Decrypted message:", decrypted);
* } catch (error) {
* console.error("Decryption failed:", error);
* }
* ```
*
* @see {@link encryptWithPublicKey} for the corresponding encryption function
*/
declare function decryptWithPrivateKey(encryptedString: string, privateKey: CryptoKey): Promise<string>;
export { type KeyPair, decryptWithPrivateKey, deserializePrivateKey, encryptWithPublicKey, exportPublicKey, generateKeyPair, importPublicKey, serializePrivateKey };