@happyvertical/encryption 0.79.0 → 0.80.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nacl-BElkPprm.js","names":[],"sources":["../../src/adapters/nacl.ts"],"sourcesContent":["import nacl from 'tweetnacl';\nimport {\n decodeBase64,\n decodeUTF8,\n encodeBase64,\n encodeUTF8,\n} from 'tweetnacl-util';\nimport { BaseEncryption } from '../shared/base.js';\nimport {\n DecryptError,\n EncryptError,\n InvalidKeyError,\n KeyError,\n SignatureError,\n} from '../shared/errors.js';\nimport type {\n DecryptOptions,\n EncryptionCapabilities,\n EncryptOptions,\n ExportKeyOptions,\n ImportKeyOptions,\n Key,\n KeyPair,\n KeyPairOptions,\n NaClOptions,\n SignOptions,\n VerifyOptions,\n} from '../shared/types.js';\n\n/**\n * NaCl/TweetNaCl encryption adapter\n *\n * Provides fast, modern cryptography using the NaCl library.\n * Supports both symmetric (secretbox) and asymmetric (box) encryption.\n *\n * @example\n * ```typescript\n * // Symmetric encryption\n * const nacl = new NaClEncryption({\n * type: 'nacl',\n * secretKey: secretKey\n * });\n *\n * const encrypted = await nacl.encryptText('Secret message');\n * const decrypted = await nacl.decryptText(encrypted);\n *\n * // Asymmetric encryption\n * const nacl = new NaClEncryption({\n * type: 'nacl',\n * publicKey: theirPublicKey,\n * secretKey: mySecretKey\n * });\n *\n * const encrypted = await nacl.encryptText('Secret message', {\n * recipientPublicKey: theirPublicKey\n * });\n * const decrypted = await nacl.decryptText(encrypted);\n * ```\n */\nexport class NaClEncryption extends BaseEncryption {\n private options: NaClOptions;\n private secretKey?: Uint8Array;\n private publicKey?: Uint8Array;\n\n constructor(options: NaClOptions) {\n super('nacl', options.debug);\n this.options = options;\n this.initializeKeys();\n }\n\n /**\n * Initialize keys from options\n */\n private initializeKeys(): void {\n const encoding = this.options.encoding || 'base64';\n\n // Initialize secret key for symmetric encryption\n if (this.options.secretKey) {\n this.secretKey = this.parseKey(this.options.secretKey, encoding);\n if (this.secretKey.length !== nacl.secretbox.keyLength) {\n throw new InvalidKeyError(\n `NaCl secret key must be ${nacl.secretbox.keyLength} bytes`,\n this.adapterType,\n );\n }\n }\n\n // Initialize public key for asymmetric encryption\n if (this.options.publicKey) {\n this.publicKey = this.parseKey(this.options.publicKey, encoding);\n if (this.publicKey.length !== nacl.box.publicKeyLength) {\n throw new InvalidKeyError(\n `NaCl public key must be ${nacl.box.publicKeyLength} bytes`,\n this.adapterType,\n );\n }\n }\n }\n\n /**\n * Parse key from various formats\n */\n private parseKey(\n key: Uint8Array | Buffer | string,\n encoding: 'base64' | 'hex' | 'utf8',\n ): Uint8Array {\n if (key instanceof Uint8Array) {\n return key;\n }\n\n if (Buffer.isBuffer(key)) {\n return new Uint8Array(key);\n }\n\n if (typeof key === 'string') {\n if (encoding === 'base64') {\n return decodeBase64(key);\n }\n if (encoding === 'hex') {\n return new Uint8Array(Buffer.from(key, 'hex'));\n }\n if (encoding === 'utf8') {\n return decodeUTF8(key);\n }\n }\n\n throw new InvalidKeyError('Invalid key format for NaCl', this.adapterType);\n }\n\n /**\n * Format key for output\n */\n private formatKey(\n key: Uint8Array,\n encoding: 'base64' | 'hex' | 'utf8' = 'base64',\n ): string {\n if (encoding === 'base64') {\n return encodeBase64(key);\n }\n if (encoding === 'hex') {\n return Buffer.from(key).toString('hex');\n }\n if (encoding === 'utf8') {\n return encodeUTF8(key);\n }\n return encodeBase64(key);\n }\n\n async encryptText(text: string, options?: EncryptOptions): Promise<string> {\n try {\n this.log('Encrypting text', { length: text.length });\n\n const message = decodeUTF8(text);\n\n // Check if asymmetric or symmetric encryption\n if (options?.recipientPublicKey) {\n // Asymmetric encryption (box)\n return this.encryptAsymmetric(message, options);\n }\n\n // Symmetric encryption (secretbox)\n return this.encryptSymmetric(message);\n } catch (error) {\n throw new EncryptError(\n `Failed to encrypt text: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async decryptText(\n encrypted: string,\n options?: DecryptOptions,\n ): Promise<string> {\n try {\n this.log('Decrypting text', { length: encrypted.length });\n\n // Decode the encrypted message\n const encryptedData = decodeBase64(encrypted);\n\n // Extract nonce and ciphertext\n const nonceLength = nacl.secretbox.nonceLength;\n const nonce = encryptedData.slice(0, nonceLength);\n const ciphertext = encryptedData.slice(nonceLength);\n\n let decrypted: Uint8Array | null;\n\n // Try asymmetric decryption first if we have keys\n if (this.publicKey && this.secretKey) {\n // Check if there's a public key in the message (for box)\n if (ciphertext.length > nacl.box.publicKeyLength) {\n const senderPublicKey = ciphertext.slice(0, nacl.box.publicKeyLength);\n const actualCiphertext = ciphertext.slice(nacl.box.publicKeyLength);\n\n decrypted = nacl.box.open(\n actualCiphertext,\n nonce,\n senderPublicKey,\n this.secretKey,\n );\n\n if (decrypted) {\n this.log('Text decrypted successfully (asymmetric)');\n return encodeUTF8(decrypted);\n }\n }\n }\n\n // Try symmetric decryption\n if (this.secretKey) {\n decrypted = nacl.secretbox.open(ciphertext, nonce, this.secretKey);\n\n if (decrypted) {\n this.log('Text decrypted successfully (symmetric)');\n return encodeUTF8(decrypted);\n }\n }\n\n throw new DecryptError(\n 'Decryption failed: invalid key or corrupted ciphertext',\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof DecryptError) {\n throw error;\n }\n throw new DecryptError(\n `Failed to decrypt text: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async encryptBuffer(\n buffer: Buffer,\n options?: EncryptOptions,\n ): Promise<Buffer> {\n try {\n this.log('Encrypting buffer', { size: buffer.length });\n\n const message = new Uint8Array(buffer);\n\n // Check if asymmetric or symmetric encryption\n if (options?.recipientPublicKey) {\n // Asymmetric encryption (box)\n const encrypted = this.encryptAsymmetric(message, options);\n return Buffer.from(decodeBase64(encrypted));\n }\n\n // Symmetric encryption (secretbox)\n const encrypted = this.encryptSymmetric(message);\n return Buffer.from(decodeBase64(encrypted));\n } catch (error) {\n throw new EncryptError(\n `Failed to encrypt buffer: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async decryptBuffer(\n buffer: Buffer,\n options?: DecryptOptions,\n ): Promise<Buffer> {\n try {\n this.log('Decrypting buffer', { size: buffer.length });\n\n // Decode the base64 buffer\n const decoded = decodeBase64(buffer.toString('base64'));\n\n // Extract nonce and ciphertext\n const nonce = decoded.slice(0, nacl.secretbox.nonceLength);\n const ciphertext = decoded.slice(nacl.secretbox.nonceLength);\n\n let decrypted: Uint8Array | null = null;\n\n // Try asymmetric decryption first if we have keys\n if (this.publicKey && this.secretKey) {\n // Check if there's a public key in the message (for box)\n if (ciphertext.length > nacl.box.publicKeyLength) {\n const senderPublicKey = ciphertext.slice(0, nacl.box.publicKeyLength);\n const actualCiphertext = ciphertext.slice(nacl.box.publicKeyLength);\n\n decrypted = nacl.box.open(\n actualCiphertext,\n nonce,\n senderPublicKey,\n this.secretKey,\n );\n\n if (decrypted) {\n this.log('Buffer decrypted successfully (asymmetric)');\n return Buffer.from(decrypted);\n }\n }\n }\n\n // Try symmetric decryption\n if (this.secretKey) {\n decrypted = nacl.secretbox.open(ciphertext, nonce, this.secretKey);\n\n if (decrypted) {\n this.log('Buffer decrypted successfully (symmetric)');\n return Buffer.from(decrypted);\n }\n }\n\n throw new DecryptError(\n 'Decryption failed: invalid key or corrupted ciphertext',\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof DecryptError) {\n throw error;\n }\n throw new DecryptError(\n `Failed to decrypt buffer: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Symmetric encryption using secretbox\n */\n private encryptSymmetric(message: Uint8Array): string {\n if (!this.secretKey) {\n throw new KeyError(\n 'Secret key required for symmetric encryption',\n this.adapterType,\n );\n }\n\n // Generate random nonce\n const nonce = nacl.randomBytes(nacl.secretbox.nonceLength);\n\n // Encrypt the message\n const ciphertext = nacl.secretbox(message, nonce, this.secretKey);\n\n // Combine nonce and ciphertext\n const encrypted = new Uint8Array(nonce.length + ciphertext.length);\n encrypted.set(nonce);\n encrypted.set(ciphertext, nonce.length);\n\n return encodeBase64(encrypted);\n }\n\n /**\n * Asymmetric encryption using box\n */\n private encryptAsymmetric(\n message: Uint8Array,\n options: EncryptOptions,\n ): string {\n if (!this.secretKey) {\n throw new KeyError(\n 'Secret key required for asymmetric encryption',\n this.adapterType,\n );\n }\n\n // Get recipient public key\n const recipientPublicKey = this.parseKey(\n options.recipientPublicKey as string | Uint8Array | Buffer,\n this.options.encoding || 'base64',\n );\n\n if (recipientPublicKey.length !== nacl.box.publicKeyLength) {\n throw new InvalidKeyError(\n `Recipient public key must be ${nacl.box.publicKeyLength} bytes`,\n this.adapterType,\n );\n }\n\n // Generate random nonce\n const nonce = nacl.randomBytes(nacl.box.nonceLength);\n\n // Encrypt the message\n const ciphertext = nacl.box(\n message,\n nonce,\n recipientPublicKey,\n this.secretKey,\n );\n\n // Include sender's public key in the message\n const senderPublicKey =\n this.publicKey ||\n nacl.box.keyPair.fromSecretKey(this.secretKey).publicKey;\n\n // Combine nonce, sender public key, and ciphertext\n const encrypted = new Uint8Array(\n nonce.length + senderPublicKey.length + ciphertext.length,\n );\n encrypted.set(nonce);\n encrypted.set(senderPublicKey, nonce.length);\n encrypted.set(ciphertext, nonce.length + senderPublicKey.length);\n\n return encodeBase64(encrypted);\n }\n\n async generateKeyPair(options?: KeyPairOptions): Promise<KeyPair> {\n try {\n this.log('Generating NaCl key pair', options);\n\n const keyType = options?.type || 'box';\n\n if (keyType === 'box' || keyType === 'ecdh') {\n // Generate encryption keypair\n const keypair = nacl.box.keyPair();\n\n this.log('Encryption key pair generated');\n\n return {\n publicKey: keypair.publicKey,\n privateKey: keypair.secretKey,\n };\n }\n\n if (keyType === 'ecdsa') {\n // Generate signing keypair\n const keypair = nacl.sign.keyPair();\n\n this.log('Signing key pair generated');\n\n return {\n publicKey: keypair.publicKey,\n privateKey: keypair.secretKey,\n };\n }\n\n throw new KeyError(\n `Unsupported key type for NaCl: ${keyType}. Use 'box' for encryption or 'sign' for signatures.`,\n this.adapterType,\n );\n } catch (error) {\n throw new KeyError(\n `Failed to generate NaCl key pair: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async importKey(\n key: string | Buffer,\n options?: ImportKeyOptions,\n ): Promise<Key> {\n try {\n this.log('Importing NaCl key');\n\n const encoding = this.options.encoding || 'base64';\n const keyData = typeof key === 'string' ? key : key.toString(encoding);\n const keyBytes = this.parseKey(keyData, encoding);\n\n const keyType = options?.type || 'public';\n const format = (options?.format || 'armored') as\n | 'armored'\n | 'binary'\n | 'pem'\n | 'der';\n\n // Validate key length\n const expectedLength =\n keyType === 'public'\n ? nacl.box.publicKeyLength\n : nacl.box.secretKeyLength;\n\n if (keyBytes.length !== expectedLength) {\n throw new InvalidKeyError(\n `NaCl ${keyType} key must be ${expectedLength} bytes`,\n this.adapterType,\n );\n }\n\n this.log('Key imported successfully');\n\n return {\n type: keyType as 'public' | 'private',\n format,\n data: keyData,\n algorithm: 'nacl',\n };\n } catch (error) {\n throw new InvalidKeyError(\n `Failed to import NaCl key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async exportKey(\n key: Key,\n options?: ExportKeyOptions,\n ): Promise<string | Buffer> {\n try {\n this.log('Exporting NaCl key');\n\n const format = options?.format || key.format || 'armored';\n // Use NaCl encoding from options or default\n const encoding = this.options.encoding || 'base64';\n\n if (typeof key.data === 'string') {\n if (format === 'binary') {\n return Buffer.from(key.data, encoding);\n }\n return key.data;\n }\n\n if (Buffer.isBuffer(key.data)) {\n if (format === 'armored') {\n return key.data.toString(encoding);\n }\n return key.data;\n }\n\n if (key.data instanceof Uint8Array) {\n if (format === 'binary') {\n return Buffer.from(key.data);\n }\n return this.formatKey(key.data, encoding);\n }\n\n throw new InvalidKeyError(\n 'Invalid key data format for export',\n this.adapterType,\n );\n } catch (error) {\n throw new KeyError(\n `Failed to export NaCl key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Sign data with signing key\n */\n async sign(\n data: string | Buffer,\n options?: SignOptions,\n ): Promise<string | Buffer> {\n try {\n this.log('Signing data');\n\n // Get signing key\n let signingKey: Uint8Array;\n\n if (options?.privateKey) {\n signingKey = this.parseKey(\n options.privateKey,\n this.options.encoding || 'base64',\n );\n } else if (this.secretKey) {\n signingKey = this.secretKey;\n } else {\n throw new KeyError('No signing key available', this.adapterType);\n }\n\n // Validate key length for signing\n if (signingKey.length !== nacl.sign.secretKeyLength) {\n throw new InvalidKeyError(\n `NaCl signing key must be ${nacl.sign.secretKeyLength} bytes`,\n this.adapterType,\n );\n }\n\n // Prepare message\n const message =\n typeof data === 'string' ? decodeUTF8(data) : new Uint8Array(data);\n\n // Sign the message\n const signed = nacl.sign(message, signingKey);\n\n this.log('Data signed successfully');\n\n if (typeof data === 'string') {\n return encodeBase64(signed);\n }\n\n return Buffer.from(signed);\n } catch (error) {\n throw new SignatureError(\n `Failed to sign data: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Verify signature\n */\n async verify(\n data: string | Buffer,\n signature: string | Buffer,\n options?: VerifyOptions,\n ): Promise<boolean> {\n try {\n this.log('Verifying signature');\n\n if (!options?.publicKey) {\n throw new KeyError(\n 'Public key required for signature verification',\n this.adapterType,\n );\n }\n\n // Get verification key\n const verificationKey = this.parseKey(\n options.publicKey,\n this.options.encoding || 'base64',\n );\n\n // Validate key length\n if (verificationKey.length !== nacl.sign.publicKeyLength) {\n throw new InvalidKeyError(\n `NaCl verification key must be ${nacl.sign.publicKeyLength} bytes`,\n this.adapterType,\n );\n }\n\n // Parse signed message\n const signedMessage =\n typeof signature === 'string'\n ? decodeBase64(signature)\n : new Uint8Array(signature);\n\n // Verify and open the signed message (extracts original message)\n const verified = nacl.sign.open(signedMessage, verificationKey);\n\n if (!verified) {\n this.log('Signature verification failed');\n return false;\n }\n\n // Compare extracted message with provided data\n const originalMessage =\n typeof data === 'string' ? decodeUTF8(data) : new Uint8Array(data);\n\n // Check if messages match\n if (verified.length !== originalMessage.length) {\n this.log('Signature verification failed: message mismatch');\n return false;\n }\n\n for (let i = 0; i < verified.length; i++) {\n if (verified[i] !== originalMessage[i]) {\n this.log('Signature verification failed: message mismatch');\n return false;\n }\n }\n\n this.log('Signature verified successfully');\n return true;\n } catch (error) {\n this.log('Signature verification failed', error);\n return false;\n }\n }\n\n async getCapabilities(): Promise<EncryptionCapabilities> {\n return {\n textEncryption: true,\n fileEncryption: true,\n bufferEncryption: true,\n streamEncryption: false,\n emailEncryption: false,\n signing: true,\n verification: true,\n keyGeneration: true,\n keyManagement: true,\n multipleRecipients: false,\n symmetricEncryption: true,\n asymmetricEncryption: true,\n };\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,421 @@
1
+ import { c as KeyError, d as SignatureError, i as EncryptError, r as DecryptError, s as InvalidKeyError, t as BaseEncryption } from "./base-qiu-WiZ0.js";
2
+ import * as crypto from "node:crypto";
3
+ //#region src/adapters/node.ts
4
+ /**
5
+ * Node.js crypto adapter
6
+ *
7
+ * Uses Node.js built-in crypto module for standard encryption algorithms
8
+ * (AES, RSA, ECDH, ECDSA, etc.).
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const crypto = new NodeCryptoEncryption({
13
+ * type: 'node',
14
+ * algorithm: 'aes-256-gcm',
15
+ * key: encryptionKey
16
+ * });
17
+ *
18
+ * const encrypted = await crypto.encryptText('Secret message');
19
+ * const decrypted = await crypto.decryptText(encrypted);
20
+ * ```
21
+ */
22
+ var NodeCryptoEncryption = class extends BaseEncryption {
23
+ options;
24
+ key;
25
+ publicKey;
26
+ privateKey;
27
+ constructor(options) {
28
+ super("node", options.debug);
29
+ this.options = options;
30
+ this.initializeKeys();
31
+ }
32
+ /**
33
+ * Initialize keys from options
34
+ */
35
+ initializeKeys() {
36
+ if (this.options.keyDerivation) this.key = this.deriveKey(this.options.keyDerivation);
37
+ else if (this.options.key) this.key = this.parseBuffer(this.options.key);
38
+ if (this.options.publicKey) this.publicKey = this.importPublicKeyObject(this.options.publicKey);
39
+ if (this.options.privateKey) this.privateKey = this.importPrivateKeyObject(this.options.privateKey, this.options.passphrase);
40
+ }
41
+ /**
42
+ * Derive key from password using PBKDF2
43
+ */
44
+ deriveKey(derivation) {
45
+ const salt = derivation.salt ? this.parseBuffer(derivation.salt) : crypto.randomBytes(16);
46
+ const iterations = derivation.iterations || 1e5;
47
+ const keyLength = derivation.keyLength || this.getKeyLength();
48
+ const digest = derivation.digest || "sha256";
49
+ return crypto.pbkdf2Sync(derivation.password, salt, iterations, keyLength, digest);
50
+ }
51
+ /**
52
+ * Get key length for current algorithm
53
+ */
54
+ getKeyLength() {
55
+ const algo = this.options.algorithm.toLowerCase();
56
+ if (algo.includes("256")) return 32;
57
+ if (algo.includes("192")) return 24;
58
+ if (algo.includes("128")) return 16;
59
+ return 32;
60
+ }
61
+ /**
62
+ * Parse buffer from string or Buffer
63
+ */
64
+ parseBuffer(data) {
65
+ if (Buffer.isBuffer(data)) return data;
66
+ const encoding = this.options.encoding || "hex";
67
+ if (encoding === "hex") return Buffer.from(data, "hex");
68
+ if (encoding === "base64") return Buffer.from(data, "base64");
69
+ if (encoding === "utf8") return Buffer.from(data, "utf8");
70
+ return Buffer.from(data, "hex");
71
+ }
72
+ /**
73
+ * Import public key from PEM/DER
74
+ */
75
+ importPublicKeyObject(key) {
76
+ try {
77
+ return crypto.createPublicKey(key);
78
+ } catch (error) {
79
+ throw new InvalidKeyError(`Failed to import public key: ${error.message}`, this.adapterType, error);
80
+ }
81
+ }
82
+ /**
83
+ * Import private key from PEM/DER
84
+ */
85
+ importPrivateKeyObject(key, passphrase) {
86
+ try {
87
+ if (passphrase) return crypto.createPrivateKey({
88
+ key,
89
+ passphrase
90
+ });
91
+ return crypto.createPrivateKey(key);
92
+ } catch (error) {
93
+ throw new InvalidKeyError(`Failed to import private key: ${error.message}`, this.adapterType, error);
94
+ }
95
+ }
96
+ /**
97
+ * Check if algorithm is symmetric (AES)
98
+ */
99
+ isSymmetric() {
100
+ const algo = this.options.algorithm.toLowerCase();
101
+ return algo.startsWith("aes-") || algo.includes("cipher");
102
+ }
103
+ /**
104
+ * Check if algorithm is RSA
105
+ */
106
+ isRSA() {
107
+ return this.options.algorithm.toLowerCase().startsWith("rsa");
108
+ }
109
+ async encryptText(text, options) {
110
+ try {
111
+ this.log("Encrypting text", { length: text.length });
112
+ if (this.isSymmetric()) return this.encryptSymmetric(Buffer.from(text, "utf8"));
113
+ if (this.isRSA()) return this.encryptAsymmetric(Buffer.from(text, "utf8"));
114
+ throw new EncryptError(`Unsupported encryption algorithm: ${this.options.algorithm}`, this.adapterType);
115
+ } catch (error) {
116
+ if (error instanceof EncryptError) throw error;
117
+ throw new EncryptError(`Failed to encrypt text: ${error.message}`, this.adapterType, error);
118
+ }
119
+ }
120
+ async decryptText(encrypted, options) {
121
+ try {
122
+ this.log("Decrypting text", { length: encrypted.length });
123
+ if (this.isSymmetric()) return this.decryptSymmetric(encrypted).toString("utf8");
124
+ if (this.isRSA()) return this.decryptAsymmetric(encrypted).toString("utf8");
125
+ throw new DecryptError(`Unsupported decryption algorithm: ${this.options.algorithm}`, this.adapterType);
126
+ } catch (error) {
127
+ if (error instanceof DecryptError) throw error;
128
+ throw new DecryptError(`Failed to decrypt text: ${error.message}`, this.adapterType, error);
129
+ }
130
+ }
131
+ async encryptBuffer(buffer, options) {
132
+ try {
133
+ this.log("Encrypting buffer", { size: buffer.length });
134
+ if (this.isSymmetric()) {
135
+ const encrypted = this.encryptSymmetric(buffer);
136
+ return Buffer.from(encrypted, "base64");
137
+ }
138
+ if (this.isRSA()) {
139
+ const encrypted = this.encryptAsymmetric(buffer);
140
+ return Buffer.from(encrypted, "base64");
141
+ }
142
+ throw new EncryptError(`Unsupported encryption algorithm: ${this.options.algorithm}`, this.adapterType);
143
+ } catch (error) {
144
+ if (error instanceof EncryptError) throw error;
145
+ throw new EncryptError(`Failed to encrypt buffer: ${error.message}`, this.adapterType, error);
146
+ }
147
+ }
148
+ async decryptBuffer(buffer, options) {
149
+ try {
150
+ this.log("Decrypting buffer", { size: buffer.length });
151
+ const base64 = buffer.toString("base64");
152
+ if (this.isSymmetric()) return this.decryptSymmetric(base64);
153
+ if (this.isRSA()) return this.decryptAsymmetric(base64);
154
+ throw new DecryptError(`Unsupported decryption algorithm: ${this.options.algorithm}`, this.adapterType);
155
+ } catch (error) {
156
+ if (error instanceof DecryptError) throw error;
157
+ throw new DecryptError(`Failed to decrypt buffer: ${error.message}`, this.adapterType, error);
158
+ }
159
+ }
160
+ /**
161
+ * Symmetric encryption (AES)
162
+ */
163
+ encryptSymmetric(data) {
164
+ if (!this.key) throw new KeyError("Encryption key required for symmetric encryption", this.adapterType);
165
+ const algorithm = this.options.algorithm;
166
+ const isGCM = algorithm.toLowerCase().includes("gcm");
167
+ const ivLength = isGCM ? 12 : 16;
168
+ const iv = this.options.iv ? this.parseBuffer(this.options.iv) : crypto.randomBytes(ivLength);
169
+ const cipher = crypto.createCipheriv(algorithm, this.key, iv);
170
+ const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
171
+ let authTag;
172
+ if (isGCM) authTag = cipher.getAuthTag();
173
+ let result;
174
+ if (authTag) result = Buffer.concat([
175
+ iv,
176
+ authTag,
177
+ encrypted
178
+ ]);
179
+ else result = Buffer.concat([iv, encrypted]);
180
+ return result.toString("base64");
181
+ }
182
+ /**
183
+ * Symmetric decryption (AES)
184
+ */
185
+ decryptSymmetric(encrypted) {
186
+ if (!this.key) throw new KeyError("Decryption key required for symmetric decryption", this.adapterType);
187
+ const algorithm = this.options.algorithm;
188
+ const isGCM = algorithm.toLowerCase().includes("gcm");
189
+ const encryptedBuffer = Buffer.from(encrypted, "base64");
190
+ const ivLength = isGCM ? 12 : 16;
191
+ const iv = encryptedBuffer.subarray(0, ivLength);
192
+ let authTag;
193
+ let ciphertext;
194
+ if (isGCM) {
195
+ authTag = encryptedBuffer.subarray(ivLength, ivLength + 16);
196
+ ciphertext = encryptedBuffer.subarray(ivLength + 16);
197
+ } else ciphertext = encryptedBuffer.subarray(ivLength);
198
+ const decipher = crypto.createDecipheriv(algorithm, this.key, iv);
199
+ if (authTag) decipher.setAuthTag(authTag);
200
+ return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
201
+ }
202
+ /**
203
+ * Asymmetric encryption (RSA)
204
+ */
205
+ encryptAsymmetric(data) {
206
+ if (!this.publicKey) throw new KeyError("Public key required for asymmetric encryption", this.adapterType);
207
+ return crypto.publicEncrypt({
208
+ key: this.publicKey,
209
+ padding: this.getRSAPadding()
210
+ }, data).toString("base64");
211
+ }
212
+ /**
213
+ * Asymmetric decryption (RSA)
214
+ */
215
+ decryptAsymmetric(encrypted) {
216
+ if (!this.privateKey) throw new KeyError("Private key required for asymmetric decryption", this.adapterType);
217
+ const encryptedBuffer = Buffer.from(encrypted, "base64");
218
+ return crypto.privateDecrypt({
219
+ key: this.privateKey,
220
+ padding: this.getRSAPadding()
221
+ }, encryptedBuffer);
222
+ }
223
+ /**
224
+ * Get RSA padding mode
225
+ */
226
+ getRSAPadding() {
227
+ const algo = this.options.algorithm.toLowerCase();
228
+ if (algo.includes("oaep")) return crypto.constants.RSA_PKCS1_OAEP_PADDING;
229
+ if (algo.includes("pss")) return crypto.constants.RSA_PKCS1_PSS_PADDING;
230
+ return crypto.constants.RSA_PKCS1_PADDING;
231
+ }
232
+ async generateKeyPair(options) {
233
+ try {
234
+ this.log("Generating key pair", options);
235
+ const keyType = options?.type || "rsa";
236
+ if (keyType === "rsa") {
237
+ const modulusLength = options?.keySize || 2048;
238
+ const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {
239
+ modulusLength,
240
+ publicKeyEncoding: {
241
+ type: "spki",
242
+ format: "pem"
243
+ },
244
+ privateKeyEncoding: {
245
+ type: "pkcs8",
246
+ format: "pem",
247
+ ...options?.passphrase && {
248
+ cipher: "aes-256-cbc",
249
+ passphrase: options.passphrase
250
+ }
251
+ }
252
+ });
253
+ this.log("RSA key pair generated");
254
+ return {
255
+ publicKey,
256
+ privateKey
257
+ };
258
+ }
259
+ if (keyType === "ecc" || keyType === "ecdh") {
260
+ const curve = options?.curve || "prime256v1";
261
+ const { publicKey, privateKey } = crypto.generateKeyPairSync("ec", {
262
+ namedCurve: curve,
263
+ publicKeyEncoding: {
264
+ type: "spki",
265
+ format: "pem"
266
+ },
267
+ privateKeyEncoding: {
268
+ type: "pkcs8",
269
+ format: "pem",
270
+ ...options?.passphrase && {
271
+ cipher: "aes-256-cbc",
272
+ passphrase: options.passphrase
273
+ }
274
+ }
275
+ });
276
+ this.log("EC key pair generated");
277
+ return {
278
+ publicKey,
279
+ privateKey
280
+ };
281
+ }
282
+ if (keyType === "ecdsa") {
283
+ const curve = options?.curve || "prime256v1";
284
+ const { publicKey, privateKey } = crypto.generateKeyPairSync("ec", {
285
+ namedCurve: curve,
286
+ publicKeyEncoding: {
287
+ type: "spki",
288
+ format: "pem"
289
+ },
290
+ privateKeyEncoding: {
291
+ type: "pkcs8",
292
+ format: "pem",
293
+ ...options?.passphrase && {
294
+ cipher: "aes-256-cbc",
295
+ passphrase: options.passphrase
296
+ }
297
+ }
298
+ });
299
+ this.log("ECDSA key pair generated");
300
+ return {
301
+ publicKey,
302
+ privateKey
303
+ };
304
+ }
305
+ throw new KeyError(`Unsupported key type for Node crypto: ${keyType}`, this.adapterType);
306
+ } catch (error) {
307
+ throw new KeyError(`Failed to generate key pair: ${error.message}`, this.adapterType, error);
308
+ }
309
+ }
310
+ async importKey(key, options) {
311
+ try {
312
+ this.log("Importing key");
313
+ const keyType = options?.type || "public";
314
+ if (keyType === "public") return {
315
+ type: "public",
316
+ format: "pem",
317
+ data: crypto.createPublicKey(key).export({
318
+ type: "spki",
319
+ format: "pem"
320
+ }).toString(),
321
+ algorithm: "node"
322
+ };
323
+ if (keyType === "private") return {
324
+ type: "private",
325
+ format: "pem",
326
+ data: (options?.passphrase ? crypto.createPrivateKey({
327
+ key,
328
+ passphrase: options.passphrase
329
+ }) : crypto.createPrivateKey(key)).export({
330
+ type: "pkcs8",
331
+ format: "pem"
332
+ }).toString(),
333
+ algorithm: "node"
334
+ };
335
+ throw new InvalidKeyError(`Unsupported key type: ${keyType}`, this.adapterType);
336
+ } catch (error) {
337
+ throw new InvalidKeyError(`Failed to import key: ${error.message}`, this.adapterType, error);
338
+ }
339
+ }
340
+ async exportKey(key, options) {
341
+ try {
342
+ this.log("Exporting key");
343
+ const format = options?.format || key.format || "pem";
344
+ if (format === "pem" || format === "armored") return key.data;
345
+ if (format === "binary" || format === "der") {
346
+ if (typeof key.data === "string") return Buffer.from(key.data);
347
+ return key.data;
348
+ }
349
+ return key.data;
350
+ } catch (error) {
351
+ throw new KeyError(`Failed to export key: ${error.message}`, this.adapterType, error);
352
+ }
353
+ }
354
+ /**
355
+ * Sign data
356
+ */
357
+ async sign(data, options) {
358
+ try {
359
+ this.log("Signing data");
360
+ const privateKey = options?.privateKey ? this.importPrivateKeyObject(options.privateKey, options.passphrase) : this.privateKey;
361
+ if (!privateKey) throw new KeyError("No private key available for signing", this.adapterType);
362
+ const message = typeof data === "string" ? Buffer.from(data, "utf8") : data;
363
+ const signature = crypto.sign(null, message, privateKey);
364
+ this.log("Data signed successfully");
365
+ if (typeof data === "string") return signature.toString("base64");
366
+ return signature;
367
+ } catch (error) {
368
+ throw new SignatureError(`Failed to sign data: ${error.message}`, this.adapterType, error);
369
+ }
370
+ }
371
+ /**
372
+ * Verify signature
373
+ */
374
+ async verify(data, signature, options) {
375
+ try {
376
+ this.log("Verifying signature");
377
+ if (!options?.publicKey) return false;
378
+ const publicKey = this.importPublicKeyObject(options.publicKey);
379
+ const message = typeof data === "string" ? Buffer.from(data, "utf8") : data;
380
+ const sig = typeof signature === "string" ? Buffer.from(signature, "base64") : signature;
381
+ const valid = crypto.verify(null, message, publicKey, sig);
382
+ this.log(valid ? "Signature verified" : "Signature verification failed");
383
+ return valid;
384
+ } catch (error) {
385
+ this.log("Signature verification failed", error);
386
+ return false;
387
+ }
388
+ }
389
+ async getCapabilities() {
390
+ const algorithm = this.options.algorithm.toLowerCase();
391
+ return {
392
+ textEncryption: true,
393
+ fileEncryption: true,
394
+ bufferEncryption: true,
395
+ streamEncryption: true,
396
+ emailEncryption: false,
397
+ signing: true,
398
+ verification: true,
399
+ keyGeneration: true,
400
+ keyManagement: true,
401
+ multipleRecipients: false,
402
+ symmetricEncryption: [
403
+ "aes-256-gcm",
404
+ "aes-256-cbc",
405
+ "aes-128-gcm",
406
+ "aes-128-cbc"
407
+ ].includes(algorithm),
408
+ asymmetricEncryption: [
409
+ "rsa",
410
+ "rsa-oaep",
411
+ "rsa-pss",
412
+ "ecdh",
413
+ "ecdsa"
414
+ ].some((algo) => algorithm.includes(algo))
415
+ };
416
+ }
417
+ };
418
+ //#endregion
419
+ export { NodeCryptoEncryption };
420
+
421
+ //# sourceMappingURL=node-Bg7R5Icq.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-Bg7R5Icq.js","names":[],"sources":["../../src/adapters/node.ts"],"sourcesContent":["import * as crypto from 'node:crypto';\nimport { BaseEncryption } from '../shared/base.js';\nimport {\n DecryptError,\n EncryptError,\n InvalidKeyError,\n KeyError,\n SignatureError,\n} from '../shared/errors.js';\nimport type {\n DecryptOptions,\n EncryptionCapabilities,\n EncryptOptions,\n ExportKeyOptions,\n ImportKeyOptions,\n Key,\n KeyPair,\n KeyPairOptions,\n NodeCryptoOptions,\n SignOptions,\n VerifyOptions,\n} from '../shared/types.js';\n\n/**\n * Node.js crypto adapter\n *\n * Uses Node.js built-in crypto module for standard encryption algorithms\n * (AES, RSA, ECDH, ECDSA, etc.).\n *\n * @example\n * ```typescript\n * const crypto = new NodeCryptoEncryption({\n * type: 'node',\n * algorithm: 'aes-256-gcm',\n * key: encryptionKey\n * });\n *\n * const encrypted = await crypto.encryptText('Secret message');\n * const decrypted = await crypto.decryptText(encrypted);\n * ```\n */\nexport class NodeCryptoEncryption extends BaseEncryption {\n private options: NodeCryptoOptions;\n private key?: Buffer;\n private publicKey?: crypto.KeyObject;\n private privateKey?: crypto.KeyObject;\n\n constructor(options: NodeCryptoOptions) {\n super('node', options.debug);\n this.options = options;\n this.initializeKeys();\n }\n\n /**\n * Initialize keys from options\n */\n private initializeKeys(): void {\n // Derive key from password if specified\n if (this.options.keyDerivation) {\n this.key = this.deriveKey(this.options.keyDerivation);\n } else if (this.options.key) {\n this.key = this.parseBuffer(this.options.key);\n }\n\n // Initialize asymmetric keys\n if (this.options.publicKey) {\n this.publicKey = this.importPublicKeyObject(this.options.publicKey);\n }\n\n if (this.options.privateKey) {\n this.privateKey = this.importPrivateKeyObject(\n this.options.privateKey,\n this.options.passphrase,\n );\n }\n }\n\n /**\n * Derive key from password using PBKDF2\n */\n private deriveKey(\n derivation: NonNullable<NodeCryptoOptions['keyDerivation']>,\n ): Buffer {\n const salt = derivation.salt\n ? this.parseBuffer(derivation.salt)\n : crypto.randomBytes(16);\n const iterations = derivation.iterations || 100000;\n const keyLength = derivation.keyLength || this.getKeyLength();\n const digest = derivation.digest || 'sha256';\n\n return crypto.pbkdf2Sync(\n derivation.password,\n salt,\n iterations,\n keyLength,\n digest,\n );\n }\n\n /**\n * Get key length for current algorithm\n */\n private getKeyLength(): number {\n const algo = this.options.algorithm.toLowerCase();\n if (algo.includes('256')) return 32;\n if (algo.includes('192')) return 24;\n if (algo.includes('128')) return 16;\n return 32; // Default to 256 bits\n }\n\n /**\n * Parse buffer from string or Buffer\n */\n private parseBuffer(data: string | Buffer): Buffer {\n if (Buffer.isBuffer(data)) return data;\n\n const encoding = this.options.encoding || 'hex';\n if (encoding === 'hex') return Buffer.from(data, 'hex');\n if (encoding === 'base64') return Buffer.from(data, 'base64');\n if (encoding === 'utf8') return Buffer.from(data, 'utf8');\n\n return Buffer.from(data, 'hex');\n }\n\n /**\n * Import public key from PEM/DER\n */\n private importPublicKeyObject(key: string | Buffer): crypto.KeyObject {\n try {\n return crypto.createPublicKey(key);\n } catch (error) {\n throw new InvalidKeyError(\n `Failed to import public key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Import private key from PEM/DER\n */\n private importPrivateKeyObject(\n key: string | Buffer,\n passphrase?: string,\n ): crypto.KeyObject {\n try {\n if (passphrase) {\n return crypto.createPrivateKey({ key, passphrase });\n }\n return crypto.createPrivateKey(key);\n } catch (error) {\n throw new InvalidKeyError(\n `Failed to import private key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Check if algorithm is symmetric (AES)\n */\n private isSymmetric(): boolean {\n const algo = this.options.algorithm.toLowerCase();\n return algo.startsWith('aes-') || algo.includes('cipher');\n }\n\n /**\n * Check if algorithm is RSA\n */\n private isRSA(): boolean {\n const algo = this.options.algorithm.toLowerCase();\n return algo.startsWith('rsa');\n }\n\n async encryptText(text: string, options?: EncryptOptions): Promise<string> {\n try {\n this.log('Encrypting text', { length: text.length });\n\n if (this.isSymmetric()) {\n return this.encryptSymmetric(Buffer.from(text, 'utf8'));\n }\n\n if (this.isRSA()) {\n return this.encryptAsymmetric(Buffer.from(text, 'utf8'));\n }\n\n throw new EncryptError(\n `Unsupported encryption algorithm: ${this.options.algorithm}`,\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof EncryptError) throw error;\n throw new EncryptError(\n `Failed to encrypt text: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async decryptText(\n encrypted: string,\n options?: DecryptOptions,\n ): Promise<string> {\n try {\n this.log('Decrypting text', { length: encrypted.length });\n\n if (this.isSymmetric()) {\n const decrypted = this.decryptSymmetric(encrypted);\n return decrypted.toString('utf8');\n }\n\n if (this.isRSA()) {\n const decrypted = this.decryptAsymmetric(encrypted);\n return decrypted.toString('utf8');\n }\n\n throw new DecryptError(\n `Unsupported decryption algorithm: ${this.options.algorithm}`,\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof DecryptError) throw error;\n throw new DecryptError(\n `Failed to decrypt text: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async encryptBuffer(\n buffer: Buffer,\n options?: EncryptOptions,\n ): Promise<Buffer> {\n try {\n this.log('Encrypting buffer', { size: buffer.length });\n\n if (this.isSymmetric()) {\n const encrypted = this.encryptSymmetric(buffer);\n return Buffer.from(encrypted, 'base64');\n }\n\n if (this.isRSA()) {\n const encrypted = this.encryptAsymmetric(buffer);\n return Buffer.from(encrypted, 'base64');\n }\n\n throw new EncryptError(\n `Unsupported encryption algorithm: ${this.options.algorithm}`,\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof EncryptError) throw error;\n throw new EncryptError(\n `Failed to encrypt buffer: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async decryptBuffer(\n buffer: Buffer,\n options?: DecryptOptions,\n ): Promise<Buffer> {\n try {\n this.log('Decrypting buffer', { size: buffer.length });\n\n const base64 = buffer.toString('base64');\n\n if (this.isSymmetric()) {\n return this.decryptSymmetric(base64);\n }\n\n if (this.isRSA()) {\n return this.decryptAsymmetric(base64);\n }\n\n throw new DecryptError(\n `Unsupported decryption algorithm: ${this.options.algorithm}`,\n this.adapterType,\n );\n } catch (error) {\n if (error instanceof DecryptError) throw error;\n throw new DecryptError(\n `Failed to decrypt buffer: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Symmetric encryption (AES)\n */\n private encryptSymmetric(data: Buffer): string {\n if (!this.key) {\n throw new KeyError(\n 'Encryption key required for symmetric encryption',\n this.adapterType,\n );\n }\n\n const algorithm = this.options.algorithm;\n const isGCM = algorithm.toLowerCase().includes('gcm');\n\n // Generate IV\n const ivLength = isGCM ? 12 : 16; // GCM uses 12 bytes, CBC uses 16\n const iv = this.options.iv\n ? this.parseBuffer(this.options.iv)\n : crypto.randomBytes(ivLength);\n\n // Create cipher\n const cipher = crypto.createCipheriv(algorithm, this.key, iv);\n\n // Encrypt\n const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);\n\n // For GCM, get auth tag\n let authTag: Buffer | undefined;\n if (isGCM) {\n authTag = (cipher as crypto.CipherGCM).getAuthTag();\n }\n\n // Combine: iv + (authTag if GCM) + encrypted\n let result: Buffer;\n if (authTag) {\n result = Buffer.concat([iv, authTag, encrypted]);\n } else {\n result = Buffer.concat([iv, encrypted]);\n }\n\n return result.toString('base64');\n }\n\n /**\n * Symmetric decryption (AES)\n */\n private decryptSymmetric(encrypted: string): Buffer {\n if (!this.key) {\n throw new KeyError(\n 'Decryption key required for symmetric decryption',\n this.adapterType,\n );\n }\n\n const algorithm = this.options.algorithm;\n const isGCM = algorithm.toLowerCase().includes('gcm');\n\n const encryptedBuffer = Buffer.from(encrypted, 'base64');\n\n // Extract IV\n const ivLength = isGCM ? 12 : 16;\n const iv = encryptedBuffer.subarray(0, ivLength);\n\n // Extract auth tag if GCM\n let authTag: Buffer | undefined;\n let ciphertext: Buffer;\n if (isGCM) {\n authTag = encryptedBuffer.subarray(ivLength, ivLength + 16);\n ciphertext = encryptedBuffer.subarray(ivLength + 16);\n } else {\n ciphertext = encryptedBuffer.subarray(ivLength);\n }\n\n // Create decipher\n const decipher = crypto.createDecipheriv(algorithm, this.key, iv);\n\n // Set auth tag for GCM\n if (authTag) {\n (decipher as crypto.DecipherGCM).setAuthTag(authTag);\n }\n\n // Decrypt\n const decrypted = Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]);\n\n return decrypted;\n }\n\n /**\n * Asymmetric encryption (RSA)\n */\n private encryptAsymmetric(data: Buffer): string {\n if (!this.publicKey) {\n throw new KeyError(\n 'Public key required for asymmetric encryption',\n this.adapterType,\n );\n }\n\n const encrypted = crypto.publicEncrypt(\n {\n key: this.publicKey,\n padding: this.getRSAPadding(),\n },\n data,\n );\n\n return encrypted.toString('base64');\n }\n\n /**\n * Asymmetric decryption (RSA)\n */\n private decryptAsymmetric(encrypted: string): Buffer {\n if (!this.privateKey) {\n throw new KeyError(\n 'Private key required for asymmetric decryption',\n this.adapterType,\n );\n }\n\n const encryptedBuffer = Buffer.from(encrypted, 'base64');\n\n const decrypted = crypto.privateDecrypt(\n {\n key: this.privateKey,\n padding: this.getRSAPadding(),\n },\n encryptedBuffer,\n );\n\n return decrypted;\n }\n\n /**\n * Get RSA padding mode\n */\n private getRSAPadding(): number {\n const algo = this.options.algorithm.toLowerCase();\n if (algo.includes('oaep')) {\n return crypto.constants.RSA_PKCS1_OAEP_PADDING;\n }\n if (algo.includes('pss')) {\n return crypto.constants.RSA_PKCS1_PSS_PADDING;\n }\n return crypto.constants.RSA_PKCS1_PADDING;\n }\n\n async generateKeyPair(options?: KeyPairOptions): Promise<KeyPair> {\n try {\n this.log('Generating key pair', options);\n\n const keyType = options?.type || 'rsa';\n\n if (keyType === 'rsa') {\n const modulusLength = options?.keySize || 2048;\n const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {\n modulusLength,\n publicKeyEncoding: {\n type: 'spki',\n format: 'pem',\n },\n privateKeyEncoding: {\n type: 'pkcs8',\n format: 'pem',\n ...(options?.passphrase && {\n cipher: 'aes-256-cbc',\n passphrase: options.passphrase,\n }),\n },\n });\n\n this.log('RSA key pair generated');\n\n return { publicKey, privateKey };\n }\n\n if (keyType === 'ecc' || keyType === 'ecdh') {\n const curve = options?.curve || 'prime256v1';\n const { publicKey, privateKey } = crypto.generateKeyPairSync('ec', {\n namedCurve: curve,\n publicKeyEncoding: {\n type: 'spki',\n format: 'pem',\n },\n privateKeyEncoding: {\n type: 'pkcs8',\n format: 'pem',\n ...(options?.passphrase && {\n cipher: 'aes-256-cbc',\n passphrase: options.passphrase,\n }),\n },\n });\n\n this.log('EC key pair generated');\n\n return { publicKey, privateKey };\n }\n\n if (keyType === 'ecdsa') {\n const curve = options?.curve || 'prime256v1';\n const { publicKey, privateKey } = crypto.generateKeyPairSync('ec', {\n namedCurve: curve,\n publicKeyEncoding: {\n type: 'spki',\n format: 'pem',\n },\n privateKeyEncoding: {\n type: 'pkcs8',\n format: 'pem',\n ...(options?.passphrase && {\n cipher: 'aes-256-cbc',\n passphrase: options.passphrase,\n }),\n },\n });\n\n this.log('ECDSA key pair generated');\n\n return { publicKey, privateKey };\n }\n\n throw new KeyError(\n `Unsupported key type for Node crypto: ${keyType}`,\n this.adapterType,\n );\n } catch (error) {\n throw new KeyError(\n `Failed to generate key pair: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async importKey(\n key: string | Buffer,\n options?: ImportKeyOptions,\n ): Promise<Key> {\n try {\n this.log('Importing key');\n\n const keyType = options?.type || 'public';\n\n if (keyType === 'public') {\n const keyObj = crypto.createPublicKey(key);\n const exported = keyObj.export({\n type: 'spki',\n format: 'pem',\n });\n\n return {\n type: 'public',\n format: 'pem',\n data: exported.toString(),\n algorithm: 'node',\n };\n }\n\n if (keyType === 'private') {\n const keyObj = options?.passphrase\n ? crypto.createPrivateKey({ key, passphrase: options.passphrase })\n : crypto.createPrivateKey(key);\n\n const exported = keyObj.export({\n type: 'pkcs8',\n format: 'pem',\n });\n\n return {\n type: 'private',\n format: 'pem',\n data: exported.toString(),\n algorithm: 'node',\n };\n }\n\n throw new InvalidKeyError(\n `Unsupported key type: ${keyType}`,\n this.adapterType,\n );\n } catch (error) {\n throw new InvalidKeyError(\n `Failed to import key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n async exportKey(\n key: Key,\n options?: ExportKeyOptions,\n ): Promise<string | Buffer> {\n try {\n this.log('Exporting key');\n\n const format = options?.format || key.format || 'pem';\n\n if (format === 'pem' || format === 'armored') {\n return key.data as string;\n }\n\n if (format === 'binary' || format === 'der') {\n if (typeof key.data === 'string') {\n return Buffer.from(key.data);\n }\n return key.data as Buffer;\n }\n\n return key.data as string;\n } catch (error) {\n throw new KeyError(\n `Failed to export key: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Sign data\n */\n async sign(\n data: string | Buffer,\n options?: SignOptions,\n ): Promise<string | Buffer> {\n try {\n this.log('Signing data');\n\n const privateKey = options?.privateKey\n ? this.importPrivateKeyObject(\n options.privateKey as string | Buffer,\n options.passphrase,\n )\n : this.privateKey;\n\n if (!privateKey) {\n throw new KeyError(\n 'No private key available for signing',\n this.adapterType,\n );\n }\n\n const message =\n typeof data === 'string' ? Buffer.from(data, 'utf8') : data;\n\n const signature = crypto.sign(null, message, privateKey);\n\n this.log('Data signed successfully');\n\n if (typeof data === 'string') {\n return signature.toString('base64');\n }\n\n return signature;\n } catch (error) {\n throw new SignatureError(\n `Failed to sign data: ${(error as Error).message}`,\n this.adapterType,\n error,\n );\n }\n }\n\n /**\n * Verify signature\n */\n async verify(\n data: string | Buffer,\n signature: string | Buffer,\n options?: VerifyOptions,\n ): Promise<boolean> {\n try {\n this.log('Verifying signature');\n\n if (!options?.publicKey) {\n return false;\n }\n\n const publicKey = this.importPublicKeyObject(\n options.publicKey as string | Buffer,\n );\n\n const message =\n typeof data === 'string' ? Buffer.from(data, 'utf8') : data;\n const sig =\n typeof signature === 'string'\n ? Buffer.from(signature, 'base64')\n : signature;\n\n const valid = crypto.verify(null, message, publicKey, sig);\n\n this.log(valid ? 'Signature verified' : 'Signature verification failed');\n\n return valid;\n } catch (error) {\n this.log('Signature verification failed', error);\n return false;\n }\n }\n\n async getCapabilities(): Promise<EncryptionCapabilities> {\n const algorithm = this.options.algorithm.toLowerCase();\n\n // Determine if algorithm is symmetric or asymmetric\n const symmetricAlgorithms = [\n 'aes-256-gcm',\n 'aes-256-cbc',\n 'aes-128-gcm',\n 'aes-128-cbc',\n ];\n const asymmetricAlgorithms = [\n 'rsa',\n 'rsa-oaep',\n 'rsa-pss',\n 'ecdh',\n 'ecdsa',\n ];\n\n const isSymmetric = symmetricAlgorithms.includes(algorithm);\n const isAsymmetric = asymmetricAlgorithms.some((algo) =>\n algorithm.includes(algo),\n );\n\n return {\n textEncryption: true,\n fileEncryption: true,\n bufferEncryption: true,\n streamEncryption: true,\n emailEncryption: false,\n signing: true,\n verification: true,\n keyGeneration: true,\n keyManagement: true,\n multipleRecipients: false,\n symmetricEncryption: isSymmetric,\n asymmetricEncryption: isAsymmetric,\n };\n }\n}\n"],"mappings":"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"}