UNPKG

@mdaemon/rsa-message

Version:

RSA message encryption, signing, decryption, and verification using webcrypto or node crypto

272 lines (271 loc) 14 kB
import { KeyPairOutput, ECDHPublicKey, SharedKeyData } from "./crypto-types"; export interface IDecryptionResult { message: string; verified: boolean; } export interface IRSAEncryptedMessage { iv: Uint8Array; encryptedMessage: ArrayBuffer; signature: ArrayBuffer; encryptedAESKey?: ArrayBuffer; } declare class RSAMessage { private privateKey; private publicKey; private verifyKey; private signKey; private publicKeys; private verifyKeys; private ecdhPrivateKey; private ecdhPublicKeys; private sharedKeys; private encryptedMasterAESKey; private masterAESKeyEncryptor; /** * Generates a new AES master key, encrypts it with the current user's publicKey, and sets it as the master key. * @returns {Promise<string>} The encrypted master AES key (base64 string) */ generateAndSetMasterAESKey(): Promise<string>; /** * Sets the encrypted master AES key (base64 string, encrypted with this user's publicKey) * @param {string} encryptedKey - The encrypted master AES key (base64 string) * @param {string} encryptor - The user ID who encrypted the key (defaults to "self") */ setEncryptedMasterAESKey(encryptedKey: string, encryptor?: string): void; /** * Decrypts and returns the master AES key as a CryptoKey. Always decrypts fresh (no persistent cache). * @returns {Promise<CryptoKey>} The decrypted AES-GCM key */ getDecryptedMasterAESKey(): Promise<CryptoKey>; /** * Encrypts the current master AES key with another user's publicKey and exports it (base64 string). * @param {string} userId - The user to encrypt the key for * @returns {Promise<string>} The encrypted master AES key (base64 string) */ exportMasterAESKeyForUser(userId: string): Promise<string>; /** * Sets the master AES key from an encrypted key (base64 string, encrypted with this user's publicKey) * @param {string} encryptedKey - The encrypted master AES key (base64 string) * @param {string} encryptor - The user ID who encrypted the key (for proper signature verification) */ setMasterAESKeyFromEncrypted(encryptedKey: string, encryptor?: string): Promise<void>; /** * Encrypts a message using the master AES key (must be set). No RSA is used. Output does not include encryptedAESKey. * @param message - The plaintext message to encrypt * @returns {Promise<IRSAEncryptedMessage>} Object containing the encrypted message, iv, and signature */ encryptWithMasterAESKey(message: string): Promise<IRSAEncryptedMessage>; /** * Decrypts a message using the master AES key (must be set). No RSA is used. Input should not include encryptedAESKey. * @param encryptedData - The encrypted message object (no encryptedAESKey) * @param sender - The ID of the user who sent the message (for signature verification) * @returns {Promise<string>} The decrypted message */ decryptWithMasterAESKey(encryptedData: IRSAEncryptedMessage, sender: string): Promise<string>; /** * Decrypts a message using the master AES key and returns verification status (does not throw on signature verification failure). * @param encryptedData - The encrypted message object (no encryptedAESKey) * @param sender - The ID of the user who sent the message (for signature verification) * @returns {Promise<IDecryptionResult>} Object containing the decrypted message and verification status */ decryptWithMasterAESKeyUnsafe(encryptedData: IRSAEncryptedMessage, sender: string): Promise<IDecryptionResult>; constructor(); get publickey(): string; get verifykey(): string; get privatekey(): string; get signkey(): string; generateAESKey(): Promise<CryptoKey>; /** * Initializes RSA keys for encryption and signing. If keys are provided, they will be used. * Otherwise, new key pairs will be generated. * * @param {string} [publicKey] - The public key for encryption * @param {string} [privateKey] - The private key for decryption * @param {string} [verifyKey] - The public key for signature verification * @param {string} [signKey] - The private key for signing * @returns {Promise<{publicKey: string, verifyKey: string}>} The public keys for encryption and verification */ init(publicKey?: string, privateKey?: string, verifyKey?: string, signKey?: string): Promise<KeyPairOutput>; private genKeyPair; private importPrivateKey; private importPublicKey; /** * Encrypts a message using RSA-AES hybrid encryption * @param message - The plaintext message to encrypt * @param userId - The ID of the recipient user whose public key will be used * @returns {Promise<IRSAEncryptedMessage>} Object containing the encrypted message components: * - iv: Initialization vector for AES-GCM * - encryptedMessage: The AES encrypted message * - encryptedAESKey: The RSA encrypted AES key * - signature: Digital signature of the message * @throws {Error} If public key is not found for the user */ /** * Encrypts a message using RSA-AES hybrid encryption, using the master AES key if set, otherwise generates a new AES key. * @param message - The plaintext message to encrypt * @param userId - The ID of the recipient user whose public key will be used * @param useMasterAESKey - If true, use the master AES key (if set) * @returns {Promise<IRSAEncryptedMessage>} Object containing the encrypted message components */ encryptMessage: (message: string, userId: string, useMasterAESKey?: boolean) => Promise<IRSAEncryptedMessage>; /** * Decrypts an encrypted message and verifies its signature. If useMasterAESKey is true and the master key is set, uses it for decryption. * @param {IRSAEncryptedMessage} encryptedData - Object containing the encrypted message components: * - iv: Initialization vector for AES-GCM * - encryptedMessage: The AES encrypted message * - encryptedAESKey: The RSA encrypted AES key (optional for master AES encryption) * - signature: Digital signature of the message * @param {string} sender - The ID of the user who sent the message * @param {boolean} useMasterAESKey - If true, use the master AES key (if set) * @returns {Promise<string>} The decrypted message * @throws {Error} If private key import fails * @throws {Error} If AES key decryption fails * @throws {Error} If AES key import fails * @throws {Error} If message decryption fails * @throws {Error} If signature verification fails */ decryptMessage: (encryptedData: IRSAEncryptedMessage, sender: string, useMasterAESKey?: boolean) => Promise<string>; /** * Decrypts an encrypted message and returns verification status (does not throw on signature verification failure). * @param encryptedData - Object containing the encrypted message components * @param sender - The ID of the user who sent the message * @param useMasterAESKey - If true, use the master AES key (if set) * @returns {Promise<IDecryptionResult>} Object containing the decrypted message and verification status */ decryptMessageUnsafe(encryptedData: IRSAEncryptedMessage, sender: string, useMasterAESKey?: boolean): Promise<IDecryptionResult>; /** * Signs a message using RSA-PSS with the user's private signing key * @param message - The message string to sign * @returns Promise that resolves with the signature as an ArrayBuffer * @throws Error if signing fails */ signMessage: (message: string) => Promise<ArrayBuffer>; /** * Verifies a message signature using RSA-PSS with the sender's public verification key * @param signature - The signature to verify as an ArrayBuffer * @param message - The original message string that was signed * @param userId - The ID of the user who signed the message * @returns Promise that resolves with boolean indicating if signature is valid * @throws Error if verification fails or public key not found */ verifySignature: (signature: ArrayBuffer, message: string, userId: string) => Promise<boolean>; /** * Sets a user's public encryption key and optionally their verification key * @param userId - The ID of the user to set keys for * @param publicKey - The public encryption key string * @param verifyKey - Optional verification key string for backwards compatibility * @throws Error if userId or publicKey are invalid */ setPublicKey(userId: string, publicKey: string, verifyKey?: string): void; /** * Sets a user's public verification key used for signature verification * @param userId - The ID of the user to set the verify key for * @param verifyKey - The verification key string * @throws Error if userId or verifyKey are invalid */ setVerifyKey(userId: string, verifyKey: string): void; /** * Checks if a public encryption key exists for a user * @param userId - The ID of the user to check * @returns True if a public key exists for the user, false otherwise */ hasPublicKey(userId: string): boolean; /** * Checks if a public verification key exists for a user * @param userId - The ID of the user to check * @returns True if a verification key exists for the user, false otherwise */ hasVerifyKey(userId: string): boolean; /** * Exports an encrypted message object to a string format * @param message - The encrypted message object to export * @returns An encoded string representation of the encrypted message */ exportEncryptedMessage(message: IRSAEncryptedMessage): string; /** * Imports an encoded string back into an encrypted message object * @param encoded - The encoded string to import * @returns The decoded IRSAEncryptedMessage object */ importEncryptedMessage(encoded: string): IRSAEncryptedMessage; /** * Generates ECDH key pair for key exchange * @returns Promise that resolves with the public key in exportable format * @throws Error if key generation fails */ generateECDHKeyPair(): Promise<ECDHPublicKey>; /** * Imports another user's ECDH public key for key exchange * @param userId - The ID of the user whose public key to import * @param publicKey - The base64 encoded ECDH public key * @throws Error if key import fails */ setECDHPublicKey(userId: string, publicKey: string): Promise<void>; /** * Derives a shared secret key using ECDH and stores it for the user * @param userId - The ID of the user to derive shared key with * @param salt - Optional salt for key derivation. If not provided, a random salt is generated * @returns The salt used for key derivation * @throws Error if key derivation fails or required keys are missing */ deriveSharedKey(userId: string, salt?: Uint8Array): Promise<Uint8Array>; /** * Encrypts a message using a derived shared key * @param message - The plaintext message to encrypt * @param userId - The ID of the user to encrypt for (must have shared key derived) * @returns Object containing the encrypted message components * @throws Error if shared key is not found or encryption fails */ encryptWithSharedKey(message: string, userId: string): Promise<SharedKeyData>; /** * Decrypts a message using a derived shared key * @param encryptedData - Object containing the encrypted message components * @param userId - The ID of the user who encrypted the message * @returns The decrypted message * @throws Error if shared key is not found or decryption fails */ decryptWithSharedKey(encryptedData: SharedKeyData, userId: string): Promise<string>; /** * Exports shared key encrypted message data to a string format * @param data - The shared key encrypted data object to export * @returns An encoded string representation of the encrypted data */ exportSharedKeyData(data: SharedKeyData): string; /** * Imports an encoded string back into a shared key data object * @param encoded - The encoded string to import * @returns The decoded SharedKeyData object */ importSharedKeyData(encoded: string): SharedKeyData; /** * Checks if a shared key exists for a user * @param userId - The ID of the user to check * @returns True if a shared key exists for the user, false otherwise */ hasSharedKey(userId: string): boolean; /** * Checks if an ECDH public key exists for a user * @param userId - The ID of the user to check * @returns True if an ECDH public key exists for the user, false otherwise */ hasECDHPublicKey(userId: string): boolean; /** * Removes shared key for a user (useful for key rotation) * @param userId - The ID of the user whose shared key to remove */ removeSharedKey(userId: string): void; /** * Removes ECDH public key for a user * @param userId - The ID of the user whose ECDH public key to remove */ removeECDHPublicKey(userId: string): void; /** * Decrypts a message using a derived shared key and returns verification status (does not throw on signature verification failure). * Note: SharedKeyData does not include signatures, so this method always returns verified: true for consistency. * @param encryptedData - Object containing the encrypted message components * @param userId - The ID of the user who encrypted the message * @returns {Promise<IDecryptionResult>} Object containing the decrypted message and verification status * @throws Error if shared key is not found or decryption fails */ decryptWithSharedKeyUnsafe(encryptedData: SharedKeyData, userId: string): Promise<IDecryptionResult>; } export default RSAMessage;