@happyvertical/encryption 0.74.8

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,551 @@
1
+ import * as crypto from "node:crypto";
2
+ import { BaseEncryption, InvalidKeyError, EncryptError, DecryptError, KeyError, SignatureError } from "../index.js";
3
+ class NodeCryptoEncryption extends BaseEncryption {
4
+ options;
5
+ key;
6
+ publicKey;
7
+ privateKey;
8
+ constructor(options) {
9
+ super("node", options.debug);
10
+ this.options = options;
11
+ this.initializeKeys();
12
+ }
13
+ /**
14
+ * Initialize keys from options
15
+ */
16
+ initializeKeys() {
17
+ if (this.options.keyDerivation) {
18
+ this.key = this.deriveKey(this.options.keyDerivation);
19
+ } else if (this.options.key) {
20
+ this.key = this.parseBuffer(this.options.key);
21
+ }
22
+ if (this.options.publicKey) {
23
+ this.publicKey = this.importPublicKeyObject(this.options.publicKey);
24
+ }
25
+ if (this.options.privateKey) {
26
+ this.privateKey = this.importPrivateKeyObject(
27
+ this.options.privateKey,
28
+ this.options.passphrase
29
+ );
30
+ }
31
+ }
32
+ /**
33
+ * Derive key from password using PBKDF2
34
+ */
35
+ deriveKey(derivation) {
36
+ const salt = derivation.salt ? this.parseBuffer(derivation.salt) : crypto.randomBytes(16);
37
+ const iterations = derivation.iterations || 1e5;
38
+ const keyLength = derivation.keyLength || this.getKeyLength();
39
+ const digest = derivation.digest || "sha256";
40
+ return crypto.pbkdf2Sync(
41
+ derivation.password,
42
+ salt,
43
+ iterations,
44
+ keyLength,
45
+ digest
46
+ );
47
+ }
48
+ /**
49
+ * Get key length for current algorithm
50
+ */
51
+ getKeyLength() {
52
+ const algo = this.options.algorithm.toLowerCase();
53
+ if (algo.includes("256")) return 32;
54
+ if (algo.includes("192")) return 24;
55
+ if (algo.includes("128")) return 16;
56
+ return 32;
57
+ }
58
+ /**
59
+ * Parse buffer from string or Buffer
60
+ */
61
+ parseBuffer(data) {
62
+ if (Buffer.isBuffer(data)) return data;
63
+ const encoding = this.options.encoding || "hex";
64
+ if (encoding === "hex") return Buffer.from(data, "hex");
65
+ if (encoding === "base64") return Buffer.from(data, "base64");
66
+ if (encoding === "utf8") return Buffer.from(data, "utf8");
67
+ return Buffer.from(data, "hex");
68
+ }
69
+ /**
70
+ * Import public key from PEM/DER
71
+ */
72
+ importPublicKeyObject(key) {
73
+ try {
74
+ return crypto.createPublicKey(key);
75
+ } catch (error) {
76
+ throw new InvalidKeyError(
77
+ `Failed to import public key: ${error.message}`,
78
+ this.adapterType,
79
+ error
80
+ );
81
+ }
82
+ }
83
+ /**
84
+ * Import private key from PEM/DER
85
+ */
86
+ importPrivateKeyObject(key, passphrase) {
87
+ try {
88
+ if (passphrase) {
89
+ return crypto.createPrivateKey({ key, passphrase });
90
+ }
91
+ return crypto.createPrivateKey(key);
92
+ } catch (error) {
93
+ throw new InvalidKeyError(
94
+ `Failed to import private key: ${error.message}`,
95
+ this.adapterType,
96
+ error
97
+ );
98
+ }
99
+ }
100
+ /**
101
+ * Check if algorithm is symmetric (AES)
102
+ */
103
+ isSymmetric() {
104
+ const algo = this.options.algorithm.toLowerCase();
105
+ return algo.startsWith("aes-") || algo.includes("cipher");
106
+ }
107
+ /**
108
+ * Check if algorithm is RSA
109
+ */
110
+ isRSA() {
111
+ const algo = this.options.algorithm.toLowerCase();
112
+ return algo.startsWith("rsa");
113
+ }
114
+ async encryptText(text, options) {
115
+ try {
116
+ this.log("Encrypting text", { length: text.length });
117
+ if (this.isSymmetric()) {
118
+ return this.encryptSymmetric(Buffer.from(text, "utf8"));
119
+ }
120
+ if (this.isRSA()) {
121
+ return this.encryptAsymmetric(Buffer.from(text, "utf8"));
122
+ }
123
+ throw new EncryptError(
124
+ `Unsupported encryption algorithm: ${this.options.algorithm}`,
125
+ this.adapterType
126
+ );
127
+ } catch (error) {
128
+ if (error instanceof EncryptError) throw error;
129
+ throw new EncryptError(
130
+ `Failed to encrypt text: ${error.message}`,
131
+ this.adapterType,
132
+ error
133
+ );
134
+ }
135
+ }
136
+ async decryptText(encrypted, options) {
137
+ try {
138
+ this.log("Decrypting text", { length: encrypted.length });
139
+ if (this.isSymmetric()) {
140
+ const decrypted = this.decryptSymmetric(encrypted);
141
+ return decrypted.toString("utf8");
142
+ }
143
+ if (this.isRSA()) {
144
+ const decrypted = this.decryptAsymmetric(encrypted);
145
+ return decrypted.toString("utf8");
146
+ }
147
+ throw new DecryptError(
148
+ `Unsupported decryption algorithm: ${this.options.algorithm}`,
149
+ this.adapterType
150
+ );
151
+ } catch (error) {
152
+ if (error instanceof DecryptError) throw error;
153
+ throw new DecryptError(
154
+ `Failed to decrypt text: ${error.message}`,
155
+ this.adapterType,
156
+ error
157
+ );
158
+ }
159
+ }
160
+ async encryptBuffer(buffer, options) {
161
+ try {
162
+ this.log("Encrypting buffer", { size: buffer.length });
163
+ if (this.isSymmetric()) {
164
+ const encrypted = this.encryptSymmetric(buffer);
165
+ return Buffer.from(encrypted, "base64");
166
+ }
167
+ if (this.isRSA()) {
168
+ const encrypted = this.encryptAsymmetric(buffer);
169
+ return Buffer.from(encrypted, "base64");
170
+ }
171
+ throw new EncryptError(
172
+ `Unsupported encryption algorithm: ${this.options.algorithm}`,
173
+ this.adapterType
174
+ );
175
+ } catch (error) {
176
+ if (error instanceof EncryptError) throw error;
177
+ throw new EncryptError(
178
+ `Failed to encrypt buffer: ${error.message}`,
179
+ this.adapterType,
180
+ error
181
+ );
182
+ }
183
+ }
184
+ async decryptBuffer(buffer, options) {
185
+ try {
186
+ this.log("Decrypting buffer", { size: buffer.length });
187
+ const base64 = buffer.toString("base64");
188
+ if (this.isSymmetric()) {
189
+ return this.decryptSymmetric(base64);
190
+ }
191
+ if (this.isRSA()) {
192
+ return this.decryptAsymmetric(base64);
193
+ }
194
+ throw new DecryptError(
195
+ `Unsupported decryption algorithm: ${this.options.algorithm}`,
196
+ this.adapterType
197
+ );
198
+ } catch (error) {
199
+ if (error instanceof DecryptError) throw error;
200
+ throw new DecryptError(
201
+ `Failed to decrypt buffer: ${error.message}`,
202
+ this.adapterType,
203
+ error
204
+ );
205
+ }
206
+ }
207
+ /**
208
+ * Symmetric encryption (AES)
209
+ */
210
+ encryptSymmetric(data) {
211
+ if (!this.key) {
212
+ throw new KeyError(
213
+ "Encryption key required for symmetric encryption",
214
+ this.adapterType
215
+ );
216
+ }
217
+ const algorithm = this.options.algorithm;
218
+ const isGCM = algorithm.toLowerCase().includes("gcm");
219
+ const ivLength = isGCM ? 12 : 16;
220
+ const iv = this.options.iv ? this.parseBuffer(this.options.iv) : crypto.randomBytes(ivLength);
221
+ const cipher = crypto.createCipheriv(algorithm, this.key, iv);
222
+ const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
223
+ let authTag;
224
+ if (isGCM) {
225
+ authTag = cipher.getAuthTag();
226
+ }
227
+ let result;
228
+ if (authTag) {
229
+ result = Buffer.concat([iv, authTag, encrypted]);
230
+ } else {
231
+ result = Buffer.concat([iv, encrypted]);
232
+ }
233
+ return result.toString("base64");
234
+ }
235
+ /**
236
+ * Symmetric decryption (AES)
237
+ */
238
+ decryptSymmetric(encrypted) {
239
+ if (!this.key) {
240
+ throw new KeyError(
241
+ "Decryption key required for symmetric decryption",
242
+ this.adapterType
243
+ );
244
+ }
245
+ const algorithm = this.options.algorithm;
246
+ const isGCM = algorithm.toLowerCase().includes("gcm");
247
+ const encryptedBuffer = Buffer.from(encrypted, "base64");
248
+ const ivLength = isGCM ? 12 : 16;
249
+ const iv = encryptedBuffer.subarray(0, ivLength);
250
+ let authTag;
251
+ let ciphertext;
252
+ if (isGCM) {
253
+ authTag = encryptedBuffer.subarray(ivLength, ivLength + 16);
254
+ ciphertext = encryptedBuffer.subarray(ivLength + 16);
255
+ } else {
256
+ ciphertext = encryptedBuffer.subarray(ivLength);
257
+ }
258
+ const decipher = crypto.createDecipheriv(algorithm, this.key, iv);
259
+ if (authTag) {
260
+ decipher.setAuthTag(authTag);
261
+ }
262
+ const decrypted = Buffer.concat([
263
+ decipher.update(ciphertext),
264
+ decipher.final()
265
+ ]);
266
+ return decrypted;
267
+ }
268
+ /**
269
+ * Asymmetric encryption (RSA)
270
+ */
271
+ encryptAsymmetric(data) {
272
+ if (!this.publicKey) {
273
+ throw new KeyError(
274
+ "Public key required for asymmetric encryption",
275
+ this.adapterType
276
+ );
277
+ }
278
+ const encrypted = crypto.publicEncrypt(
279
+ {
280
+ key: this.publicKey,
281
+ padding: this.getRSAPadding()
282
+ },
283
+ data
284
+ );
285
+ return encrypted.toString("base64");
286
+ }
287
+ /**
288
+ * Asymmetric decryption (RSA)
289
+ */
290
+ decryptAsymmetric(encrypted) {
291
+ if (!this.privateKey) {
292
+ throw new KeyError(
293
+ "Private key required for asymmetric decryption",
294
+ this.adapterType
295
+ );
296
+ }
297
+ const encryptedBuffer = Buffer.from(encrypted, "base64");
298
+ const decrypted = crypto.privateDecrypt(
299
+ {
300
+ key: this.privateKey,
301
+ padding: this.getRSAPadding()
302
+ },
303
+ encryptedBuffer
304
+ );
305
+ return decrypted;
306
+ }
307
+ /**
308
+ * Get RSA padding mode
309
+ */
310
+ getRSAPadding() {
311
+ const algo = this.options.algorithm.toLowerCase();
312
+ if (algo.includes("oaep")) {
313
+ return crypto.constants.RSA_PKCS1_OAEP_PADDING;
314
+ }
315
+ if (algo.includes("pss")) {
316
+ return crypto.constants.RSA_PKCS1_PSS_PADDING;
317
+ }
318
+ return crypto.constants.RSA_PKCS1_PADDING;
319
+ }
320
+ async generateKeyPair(options) {
321
+ try {
322
+ this.log("Generating key pair", options);
323
+ const keyType = options?.type || "rsa";
324
+ if (keyType === "rsa") {
325
+ const modulusLength = options?.keySize || 2048;
326
+ const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {
327
+ modulusLength,
328
+ publicKeyEncoding: {
329
+ type: "spki",
330
+ format: "pem"
331
+ },
332
+ privateKeyEncoding: {
333
+ type: "pkcs8",
334
+ format: "pem",
335
+ ...options?.passphrase && {
336
+ cipher: "aes-256-cbc",
337
+ passphrase: options.passphrase
338
+ }
339
+ }
340
+ });
341
+ this.log("RSA key pair generated");
342
+ return { publicKey, privateKey };
343
+ }
344
+ if (keyType === "ecc" || keyType === "ecdh") {
345
+ const curve = options?.curve || "prime256v1";
346
+ const { publicKey, privateKey } = crypto.generateKeyPairSync("ec", {
347
+ namedCurve: curve,
348
+ publicKeyEncoding: {
349
+ type: "spki",
350
+ format: "pem"
351
+ },
352
+ privateKeyEncoding: {
353
+ type: "pkcs8",
354
+ format: "pem",
355
+ ...options?.passphrase && {
356
+ cipher: "aes-256-cbc",
357
+ passphrase: options.passphrase
358
+ }
359
+ }
360
+ });
361
+ this.log("EC key pair generated");
362
+ return { publicKey, privateKey };
363
+ }
364
+ if (keyType === "ecdsa") {
365
+ const curve = options?.curve || "prime256v1";
366
+ const { publicKey, privateKey } = crypto.generateKeyPairSync("ec", {
367
+ namedCurve: curve,
368
+ publicKeyEncoding: {
369
+ type: "spki",
370
+ format: "pem"
371
+ },
372
+ privateKeyEncoding: {
373
+ type: "pkcs8",
374
+ format: "pem",
375
+ ...options?.passphrase && {
376
+ cipher: "aes-256-cbc",
377
+ passphrase: options.passphrase
378
+ }
379
+ }
380
+ });
381
+ this.log("ECDSA key pair generated");
382
+ return { publicKey, privateKey };
383
+ }
384
+ throw new KeyError(
385
+ `Unsupported key type for Node crypto: ${keyType}`,
386
+ this.adapterType
387
+ );
388
+ } catch (error) {
389
+ throw new KeyError(
390
+ `Failed to generate key pair: ${error.message}`,
391
+ this.adapterType,
392
+ error
393
+ );
394
+ }
395
+ }
396
+ async importKey(key, options) {
397
+ try {
398
+ this.log("Importing key");
399
+ const keyType = options?.type || "public";
400
+ if (keyType === "public") {
401
+ const keyObj = crypto.createPublicKey(key);
402
+ const exported = keyObj.export({
403
+ type: "spki",
404
+ format: "pem"
405
+ });
406
+ return {
407
+ type: "public",
408
+ format: "pem",
409
+ data: exported.toString(),
410
+ algorithm: "node"
411
+ };
412
+ }
413
+ if (keyType === "private") {
414
+ const keyObj = options?.passphrase ? crypto.createPrivateKey({ key, passphrase: options.passphrase }) : crypto.createPrivateKey(key);
415
+ const exported = keyObj.export({
416
+ type: "pkcs8",
417
+ format: "pem"
418
+ });
419
+ return {
420
+ type: "private",
421
+ format: "pem",
422
+ data: exported.toString(),
423
+ algorithm: "node"
424
+ };
425
+ }
426
+ throw new InvalidKeyError(
427
+ `Unsupported key type: ${keyType}`,
428
+ this.adapterType
429
+ );
430
+ } catch (error) {
431
+ throw new InvalidKeyError(
432
+ `Failed to import key: ${error.message}`,
433
+ this.adapterType,
434
+ error
435
+ );
436
+ }
437
+ }
438
+ async exportKey(key, options) {
439
+ try {
440
+ this.log("Exporting key");
441
+ const format = options?.format || key.format || "pem";
442
+ if (format === "pem" || format === "armored") {
443
+ return key.data;
444
+ }
445
+ if (format === "binary" || format === "der") {
446
+ if (typeof key.data === "string") {
447
+ return Buffer.from(key.data);
448
+ }
449
+ return key.data;
450
+ }
451
+ return key.data;
452
+ } catch (error) {
453
+ throw new KeyError(
454
+ `Failed to export key: ${error.message}`,
455
+ this.adapterType,
456
+ error
457
+ );
458
+ }
459
+ }
460
+ /**
461
+ * Sign data
462
+ */
463
+ async sign(data, options) {
464
+ try {
465
+ this.log("Signing data");
466
+ const privateKey = options?.privateKey ? this.importPrivateKeyObject(
467
+ options.privateKey,
468
+ options.passphrase
469
+ ) : this.privateKey;
470
+ if (!privateKey) {
471
+ throw new KeyError(
472
+ "No private key available for signing",
473
+ this.adapterType
474
+ );
475
+ }
476
+ const message = typeof data === "string" ? Buffer.from(data, "utf8") : data;
477
+ const signature = crypto.sign(null, message, privateKey);
478
+ this.log("Data signed successfully");
479
+ if (typeof data === "string") {
480
+ return signature.toString("base64");
481
+ }
482
+ return signature;
483
+ } catch (error) {
484
+ throw new SignatureError(
485
+ `Failed to sign data: ${error.message}`,
486
+ this.adapterType,
487
+ error
488
+ );
489
+ }
490
+ }
491
+ /**
492
+ * Verify signature
493
+ */
494
+ async verify(data, signature, options) {
495
+ try {
496
+ this.log("Verifying signature");
497
+ if (!options?.publicKey) {
498
+ return false;
499
+ }
500
+ const publicKey = this.importPublicKeyObject(
501
+ options.publicKey
502
+ );
503
+ const message = typeof data === "string" ? Buffer.from(data, "utf8") : data;
504
+ const sig = typeof signature === "string" ? Buffer.from(signature, "base64") : signature;
505
+ const valid = crypto.verify(null, message, publicKey, sig);
506
+ this.log(valid ? "Signature verified" : "Signature verification failed");
507
+ return valid;
508
+ } catch (error) {
509
+ this.log("Signature verification failed", error);
510
+ return false;
511
+ }
512
+ }
513
+ async getCapabilities() {
514
+ const algorithm = this.options.algorithm.toLowerCase();
515
+ const symmetricAlgorithms = [
516
+ "aes-256-gcm",
517
+ "aes-256-cbc",
518
+ "aes-128-gcm",
519
+ "aes-128-cbc"
520
+ ];
521
+ const asymmetricAlgorithms = [
522
+ "rsa",
523
+ "rsa-oaep",
524
+ "rsa-pss",
525
+ "ecdh",
526
+ "ecdsa"
527
+ ];
528
+ const isSymmetric = symmetricAlgorithms.includes(algorithm);
529
+ const isAsymmetric = asymmetricAlgorithms.some(
530
+ (algo) => algorithm.includes(algo)
531
+ );
532
+ return {
533
+ textEncryption: true,
534
+ fileEncryption: true,
535
+ bufferEncryption: true,
536
+ streamEncryption: true,
537
+ emailEncryption: false,
538
+ signing: true,
539
+ verification: true,
540
+ keyGeneration: true,
541
+ keyManagement: true,
542
+ multipleRecipients: false,
543
+ symmetricEncryption: isSymmetric,
544
+ asymmetricEncryption: isAsymmetric
545
+ };
546
+ }
547
+ }
548
+ export {
549
+ NodeCryptoEncryption
550
+ };
551
+ //# sourceMappingURL=node-nfBpcQQH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-nfBpcQQH.js","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"],"names":[],"mappings":"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"}