@alessiofrittoli/crypto-cipher 3.0.0-alpha.3 → 3.0.0
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.
- package/README.md +507 -281
- package/dist/{index-B9WIVWrs.d.mts → index-DWiR3kkc.d.mts} +43 -43
- package/dist/{index-B9WIVWrs.d.ts → index-DWiR3kkc.d.ts} +43 -43
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/types.d.mts +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -22,19 +22,23 @@
|
|
|
22
22
|
|
|
23
23
|
- [Getting started](#getting-started)
|
|
24
24
|
- [Key features](#key-features)
|
|
25
|
+
- [What's changed](#whats-changed)
|
|
26
|
+
- [Migration guide](#migration-guide)
|
|
25
27
|
- [API Reference](#api-reference)
|
|
26
|
-
- [Importing the library](#importing-the-library)
|
|
27
28
|
- [Constants](#constants)
|
|
28
29
|
- [Methods](#methods)
|
|
29
|
-
- [`Cipher.
|
|
30
|
-
- [`Cipher.
|
|
31
|
-
- [`Cipher.
|
|
32
|
-
- [`Cipher.
|
|
33
|
-
- [`Cipher.
|
|
34
|
-
- [`Cipher.
|
|
30
|
+
- [`Cipher.Encrypt()`](#cipherencrypt)
|
|
31
|
+
- [`Cipher.Decrypt()`](#cipherdecrypt)
|
|
32
|
+
- [`Cipher.HybridEncrypt()`](#cipherhybridencrypt)
|
|
33
|
+
- [`Cipher.HybridDecrypt()`](#cipherhybriddecrypt)
|
|
34
|
+
- [`Cipher.stream.Encrypt()`](#cipherstreamencrypt)
|
|
35
|
+
- [`Cipher.stream.Decrypt()`](#cipherstreamdecrypt)
|
|
36
|
+
- [`Cipher.stream.HybridEncrypt()`](#cipherstreamhybridencrypt)
|
|
37
|
+
- [`Cipher.stream.HybridDecrypt()`](#cipherstreamhybriddecrypt)
|
|
35
38
|
- [Types](#types)
|
|
36
39
|
- [Examples](#examples)
|
|
37
40
|
- [In-memory data buffer encryption/decryption](#in-memory-data-buffer-encryptiondecryption)
|
|
41
|
+
- [In-memory data buffer hybrid encryption/decryption](#in-memory-data-buffer-hybrid-encryptiondecryption)
|
|
38
42
|
- [In-memory data stream encryption/decryption](#in-memory-data-stream-encryptiondecryption)
|
|
39
43
|
- [In-memory data stream with hybrid encryption/decryption](#in-memory-data-stream-with-hybrid-encryptiondecryption)
|
|
40
44
|
- [File based data stream encryption/decryption](#file-based-data-stream-encryptiondecryption)
|
|
@@ -72,17 +76,13 @@ pnpm i @alessiofrittoli/crypto-cipher
|
|
|
72
76
|
|
|
73
77
|
- Supports multiple AES algorithms (`CCM`, `GCM`, `OCB`, `CBC`) and even `chacha20-poly1305`.
|
|
74
78
|
- In-memory buffer encryption and decrpytion.
|
|
75
|
-
- Robust support for encrypting and decrypting streams (in-memory and file based)
|
|
79
|
+
- Robust support for encrypting and decrypting streams (in-memory and file based).
|
|
76
80
|
- Hybrid encryption methods for combining symmetric and asymmetric cryptography.
|
|
77
81
|
|
|
78
|
-
#### Options Management
|
|
79
|
-
|
|
80
|
-
- A solid options resolver mechanism ensures consistent handling of defaults and constraints.
|
|
81
|
-
|
|
82
82
|
#### Security Considerations
|
|
83
83
|
|
|
84
84
|
- Random `salt` and `IV` generation.
|
|
85
|
-
- Authenticated encryption modes with proper `authTag` and `Additional Authenticated Data` handling.
|
|
85
|
+
- AEAD - Authenticated encryption modes with proper `authTag` and `Additional Authenticated Data` handling.
|
|
86
86
|
|
|
87
87
|
#### Readable and Modular
|
|
88
88
|
|
|
@@ -91,6 +91,128 @@ pnpm i @alessiofrittoli/crypto-cipher
|
|
|
91
91
|
|
|
92
92
|
---
|
|
93
93
|
|
|
94
|
+
### What's Changed
|
|
95
|
+
|
|
96
|
+
🎉 Core updates in the latest release:
|
|
97
|
+
|
|
98
|
+
- `Cipher` methods have been refactored to provide a solid and easy usage
|
|
99
|
+
- [`Cipher.HybridEncrypt()`](#cipherhybridencrypt) and [`Cipher.HybridDecrypt()`](#cipherhybriddecrypt) have been added. These methods will allow you to encrypt/decrypt in-memory buffer data using hybrid encryption algorithms.
|
|
100
|
+
- `Cipher.stream` subgroup has been added to keep method names consistent across the library.
|
|
101
|
+
- hybrid encryption doesn't require a password anymore which was redundant. an RSA key pair is all what you need.
|
|
102
|
+
- providing RSA key length during hybrid decryption is no longer needed.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### Migration guide
|
|
107
|
+
|
|
108
|
+
#### Migrating from v2.x.x to v3.0.0
|
|
109
|
+
|
|
110
|
+
**`Cipher.encrypt()`**
|
|
111
|
+
|
|
112
|
+
Is now renamed to **`Cipher.Encrypt()`**. It's API implementation remain the same.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
**`Cipher.decrypt()`**
|
|
117
|
+
|
|
118
|
+
Is now renamed to **`Cipher.Decrypt()`**. It's API implementation remain the same.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
**`Cipher.streamEncrypt()`**
|
|
123
|
+
|
|
124
|
+
**Before**
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
await Cipher.streamEncrypt(password, { input, output }).encrypt();
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Now**
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
await Cipher.stream.Encrypt(password, { input, output });
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
**`Cipher.streamDecrypt()`**
|
|
139
|
+
|
|
140
|
+
**Before**
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
const { decrypt } = await Cipher.streamDecrypt(password, { input, output });
|
|
144
|
+
|
|
145
|
+
await decrypt();
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Now**
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
await Cipher.stream.Decrypt(password, { input, output });
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
**`Cipher.hybridEncrypt()`**
|
|
157
|
+
|
|
158
|
+
**Before**
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
const { encrypt } = Cipher.hybridEncrypt(
|
|
162
|
+
password,
|
|
163
|
+
{
|
|
164
|
+
key: keyPair.publicKey,
|
|
165
|
+
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
|
166
|
+
oaepHash: "SHA-256",
|
|
167
|
+
},
|
|
168
|
+
{ input, output }
|
|
169
|
+
);
|
|
170
|
+
await encrypt();
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Now**
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
await Cipher.stream.HybridEncrypt(keyPair.publicKey, { input, output });
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
**`Cipher.hybridDecrypt()`**
|
|
182
|
+
|
|
183
|
+
**Before**
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
const { decrypt } = await Cipher.hybridDecrypt(
|
|
187
|
+
{
|
|
188
|
+
key: keyPair.privateKey,
|
|
189
|
+
passphrase: passphrase,
|
|
190
|
+
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
|
191
|
+
oaepHash: "SHA-256",
|
|
192
|
+
},
|
|
193
|
+
{ input, output, rsaKeyLength }
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
await decrypt();
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**Now**
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
await Cipher.stream.HybridDecrypt(
|
|
203
|
+
{ key: keyPair.privateKey, passphrase },
|
|
204
|
+
{ input, output }
|
|
205
|
+
);
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Or even**
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
await Cipher.stream.HybridDecrypt(keyPair.privateKey, { input, output });
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
94
216
|
### API Reference
|
|
95
217
|
|
|
96
218
|
#### Constants
|
|
@@ -170,48 +292,56 @@ Specifies default AES algorithms for buffer and stream operations.
|
|
|
170
292
|
<details>
|
|
171
293
|
<summary>Properties</summary>
|
|
172
294
|
|
|
173
|
-
| Operation | Algorithm | Description
|
|
174
|
-
| --------- | ------------- |
|
|
175
|
-
| `buffer` | `aes-256-gcm` | Default algorithm used for buffer data encryption/decryption
|
|
176
|
-
| `stream` | `aes-256-cbc` | Default algorithm used for stream encryption/decryption
|
|
295
|
+
| Operation | Algorithm | Description |
|
|
296
|
+
| --------- | ------------- | ------------------------------------------------------------------------------------- |
|
|
297
|
+
| `buffer` | `aes-256-gcm` | Default algorithm used for buffer data encryption/decryption |
|
|
298
|
+
| `stream` | `aes-256-cbc` | Default algorithm used for stream encryption/decryption (Cipher Block Chaining mode). |
|
|
177
299
|
|
|
178
300
|
</details>
|
|
179
301
|
|
|
180
302
|
---
|
|
181
303
|
|
|
182
|
-
##### `Cipher.
|
|
304
|
+
##### `Cipher.ALGORITHM`
|
|
183
305
|
|
|
184
|
-
|
|
306
|
+
An object defining algorithm names.
|
|
185
307
|
|
|
186
308
|
<details>
|
|
187
309
|
<summary>Properties</summary>
|
|
188
310
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
311
|
+
| Property | Value |
|
|
312
|
+
| ---------------- | ------------------- |
|
|
313
|
+
| `AES_128_CBC` | 'aes-128-cbc' |
|
|
314
|
+
| `AES_192_CBC` | 'aes-192-cbc' |
|
|
315
|
+
| `AES_256_CBC` | 'aes-256-cbc' |
|
|
316
|
+
| `AES_128_CCM` | 'aes-128-ccm' |
|
|
317
|
+
| `AES_192_CCM` | 'aes-192-ccm' |
|
|
318
|
+
| `AES_256_CCM` | 'aes-256-ccm' |
|
|
319
|
+
| `AES_128_GCM` | 'aes-128-gcm' |
|
|
320
|
+
| `AES_192_GCM` | 'aes-192-gcm' |
|
|
321
|
+
| `AES_256_GCM` | 'aes-256-gcm' |
|
|
322
|
+
| `AES_128_OCB` | 'aes-128-ocb' |
|
|
323
|
+
| `AES_192_OCB` | 'aes-192-ocb' |
|
|
324
|
+
| `AES_256_OCB` | 'aes-256-ocb' |
|
|
325
|
+
| `CHACHA_20_POLY` | 'chacha20-poly1305' |
|
|
202
326
|
|
|
203
327
|
</details>
|
|
204
328
|
|
|
205
329
|
---
|
|
206
330
|
|
|
331
|
+
##### `Cipher.ALGORITHMS`
|
|
332
|
+
|
|
333
|
+
An array of supported AES algorithms. This array includes all values in [`Cipher.ALGORITHM`](#cipheralgorithm) constant.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
207
337
|
#### Methods
|
|
208
338
|
|
|
209
|
-
##### `Cipher.
|
|
339
|
+
##### `Cipher.Encrypt()`
|
|
210
340
|
|
|
211
341
|
Encrypts an in-memory data buffer.
|
|
212
342
|
|
|
213
|
-
|
|
214
|
-
Use [`Cipher.
|
|
343
|
+
> [!WARNING]
|
|
344
|
+
> This is not suitable for large data encryption. Use [`Cipher.stream.Encrypt()`](#cipherstreamencrypt) or [`Cipher.stream.HybridEncrypt()`](#cipherstreamhybridencrypt) methods for large data encryption.
|
|
215
345
|
|
|
216
346
|
<details>
|
|
217
347
|
|
|
@@ -233,7 +363,7 @@ Use [`Cipher.streamEncrypt()`](#cipherstreamencrypt) or [`Cipher.hybridStreamEnc
|
|
|
233
363
|
|
|
234
364
|
Type: `Buffer`
|
|
235
365
|
|
|
236
|
-
|
|
366
|
+
The encrypted result buffer.
|
|
237
367
|
|
|
238
368
|
</details>
|
|
239
369
|
|
|
@@ -245,12 +375,12 @@ Type: `Buffer`
|
|
|
245
375
|
|
|
246
376
|
---
|
|
247
377
|
|
|
248
|
-
##### `Cipher.
|
|
378
|
+
##### `Cipher.Decrypt()`
|
|
249
379
|
|
|
250
380
|
Decrypts an in-memory data buffer.
|
|
251
381
|
|
|
252
|
-
|
|
253
|
-
Use [`Cipher.
|
|
382
|
+
> [!WARNING]
|
|
383
|
+
> This is not suitable for large data decryption. Use [`Cipher.stream.Decrypt()`](#cipherstreamdecrypt) or [`Cipher.stream.HybridDecrypt()`](#cipherstreamhybriddecrypt) methods for large data decryption.
|
|
254
384
|
|
|
255
385
|
<details>
|
|
256
386
|
|
|
@@ -272,7 +402,7 @@ Use [`Cipher.streamDecrypt()`](#cipherstreamdecrypt) or [`Cipher.hybridStreamDec
|
|
|
272
402
|
|
|
273
403
|
Type: `Buffer`
|
|
274
404
|
|
|
275
|
-
|
|
405
|
+
The decrypted result buffer.
|
|
276
406
|
|
|
277
407
|
</details>
|
|
278
408
|
|
|
@@ -284,18 +414,34 @@ Type: `Buffer`
|
|
|
284
414
|
|
|
285
415
|
---
|
|
286
416
|
|
|
287
|
-
##### `Cipher.
|
|
417
|
+
##### `Cipher.HybridEncrypt()`
|
|
288
418
|
|
|
289
|
-
Encrypts
|
|
419
|
+
Encrypts in-memory data using hybrid encryption.
|
|
420
|
+
|
|
421
|
+
> [!WARNING]
|
|
422
|
+
> This is not suitable for large data encryption. Use [`Cipher.stream.HybridEncrypt()`](#cipherstreamhybridencrypt) method for large data encryption.
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
> [!WARNING]
|
|
427
|
+
> Please, note that when using hybrid encryption/decryption algorithms:
|
|
428
|
+
>
|
|
429
|
+
> - an RSA keypair is required.
|
|
430
|
+
> - if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or `chacha20-poly1305` algorithm:
|
|
431
|
+
> - aes-128-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
432
|
+
> - aes-192-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
433
|
+
> - aes-256-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
434
|
+
> - chacha20-poly1305 (`type` can only be `pkcs1`)
|
|
290
435
|
|
|
291
436
|
<details>
|
|
292
437
|
|
|
293
|
-
<summary>Parameters</summary>
|
|
438
|
+
<summary style="cursor:pointer">Parameters</summary>
|
|
294
439
|
|
|
295
|
-
|
|
|
296
|
-
| --------- |
|
|
297
|
-
| `
|
|
298
|
-
| `
|
|
440
|
+
| Parameter | Type | Default | Description |
|
|
441
|
+
| --------- | ------------------------- | ------- | ------------------------------ |
|
|
442
|
+
| `data` | `CoerceToUint8ArrayInput` | - | The data to encrypt. |
|
|
443
|
+
| `key` | `crypto.KeyLike` | - | The RSA Public Key. |
|
|
444
|
+
| `options` | `Cph.Options` | - | (Optional) Additional options. |
|
|
299
445
|
|
|
300
446
|
</details>
|
|
301
447
|
|
|
@@ -305,35 +451,48 @@ Encrypts a `Readable` stream to a `Writable` stream.
|
|
|
305
451
|
|
|
306
452
|
<summary>Returns</summary>
|
|
307
453
|
|
|
308
|
-
Type: `
|
|
454
|
+
Type: `Buffer`
|
|
309
455
|
|
|
310
|
-
|
|
311
|
-
- a new instance of `crypto.Cipheriv` allowing you to add listeners to the `cipher` encryption process.
|
|
312
|
-
- the actual `encrypt` callback that must be called and awaited in order to start the encryption process.
|
|
456
|
+
The encrypted result buffer.
|
|
313
457
|
|
|
314
458
|
</details>
|
|
315
459
|
|
|
316
460
|
---
|
|
317
461
|
|
|
318
462
|
- See [`CoerceToUint8ArrayInput`](#coercetouint8arrayinput) for more informations about supported input data types.
|
|
319
|
-
- See [`Cph.
|
|
320
|
-
- See [In-memory data
|
|
321
|
-
- See [File based data stream encryption/decryption](#file-based-data-stream-encryptiondecryption) examples.
|
|
463
|
+
- See [`Cph.Options`](#cphoptionst) for more informations about additional decryption options.
|
|
464
|
+
- See [In-memory data buffer hybrid encryption/decryption](#in-memory-data-buffer-hybrid-encryptiondecryption) example.
|
|
322
465
|
|
|
323
466
|
---
|
|
324
467
|
|
|
325
|
-
##### `Cipher.
|
|
468
|
+
##### `Cipher.HybridDecrypt()`
|
|
469
|
+
|
|
470
|
+
Decrypts in-memory data using hybrid encryption.
|
|
471
|
+
|
|
472
|
+
> [!WARNING]
|
|
473
|
+
> This is not suitable for large data decryption. Use [`Cipher.stream.HybridDecrypt()`](#cipherstreamhybriddecrypt) method for large data decryption.
|
|
474
|
+
|
|
475
|
+
---
|
|
326
476
|
|
|
327
|
-
|
|
477
|
+
> [!WARNING]
|
|
478
|
+
> Please, note that when using hybrid encryption/decryption algorithms:
|
|
479
|
+
>
|
|
480
|
+
> - an RSA keypair is required.
|
|
481
|
+
> - if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or `chacha20-poly1305` algorithm:
|
|
482
|
+
> - aes-128-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
483
|
+
> - aes-192-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
484
|
+
> - aes-256-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
485
|
+
> - chacha20-poly1305 (`type` can only be `pkcs1`)
|
|
328
486
|
|
|
329
487
|
<details>
|
|
330
488
|
|
|
331
|
-
<summary>Parameters</summary>
|
|
489
|
+
<summary style="cursor:pointer">Parameters</summary>
|
|
332
490
|
|
|
333
|
-
|
|
|
334
|
-
| --------- |
|
|
335
|
-
| `
|
|
336
|
-
| `
|
|
491
|
+
| Parameter | Type | Default | Description |
|
|
492
|
+
| --------- | ------------------------- | ------- | ------------------------------ |
|
|
493
|
+
| `data` | `CoerceToUint8ArrayInput` | - | The data to encrypt. |
|
|
494
|
+
| `key` | `Cph.PrivateKey` | - | The RSA Private Key. |
|
|
495
|
+
| `options` | `Cph.Options` | - | (Optional) Additional options. |
|
|
337
496
|
|
|
338
497
|
</details>
|
|
339
498
|
|
|
@@ -341,38 +500,38 @@ Decrypts a `Readable` stream to a `Writable` stream.
|
|
|
341
500
|
|
|
342
501
|
<details>
|
|
343
502
|
|
|
344
|
-
<summary>Returns</summary>
|
|
503
|
+
<summary style="cursor:pointer">Returns</summary>
|
|
345
504
|
|
|
346
|
-
Type: `
|
|
505
|
+
Type: `Buffer`.
|
|
347
506
|
|
|
348
|
-
|
|
349
|
-
- a new instance of `crypto.Decipheriv` allowing you to add listeners to the `decipher` decryption process.
|
|
350
|
-
- the actual `decrypt` callback that must be called and awaited in order to start the decryption process.
|
|
507
|
+
The encrypted result Buffer.
|
|
351
508
|
|
|
352
509
|
</details>
|
|
353
510
|
|
|
354
511
|
---
|
|
355
512
|
|
|
356
513
|
- See [`CoerceToUint8ArrayInput`](#coercetouint8arrayinput) for more informations about supported input data types.
|
|
357
|
-
- See [`Cph.
|
|
358
|
-
- See [
|
|
359
|
-
- See [
|
|
514
|
+
- See [`Cph.PrivateKey`](#cphprivatekey) for accepted formats.
|
|
515
|
+
- See [`Cph.Options`](#cphoptionst) for more informations about additional decryption options.
|
|
516
|
+
- See [In-memory data buffer hybrid encryption/decryption](#in-memory-data-buffer-hybrid-encryptiondecryption) example.
|
|
360
517
|
|
|
361
518
|
---
|
|
362
519
|
|
|
363
|
-
##### `Cipher.
|
|
520
|
+
##### `Cipher.stream.Encrypt()`
|
|
364
521
|
|
|
365
|
-
|
|
522
|
+
Encrypt stream data.
|
|
366
523
|
|
|
367
524
|
<details>
|
|
368
525
|
|
|
369
526
|
<summary>Parameters</summary>
|
|
370
527
|
|
|
371
|
-
| Name
|
|
372
|
-
|
|
|
373
|
-
| `secret`
|
|
374
|
-
| `
|
|
375
|
-
| `options`
|
|
528
|
+
| Name | Type | Default | Description |
|
|
529
|
+
| ------------------- | --------------------------- | ------------- | -------------------------------------------------------- |
|
|
530
|
+
| `secret` | `CoerceToUint8ArrayInput` | - | The secret key used to encrypt the data. |
|
|
531
|
+
| `options` | `Cph.Stream.EncryptOptions` | - | An object defining required options. |
|
|
532
|
+
| `options.input` | `Readable` | - | The `Readable` Stream where raw data to encrypt is read. |
|
|
533
|
+
| `options.output` | `Writable` | - | The `Writable` Stream where encrypted data is written. |
|
|
534
|
+
| `options.algorithm` | `Cph.CBCTypes` | `aes-256-cbc` | One of the Cipher Block Chaining algorithm. |
|
|
376
535
|
|
|
377
536
|
</details>
|
|
378
537
|
|
|
@@ -380,37 +539,127 @@ Encrypts a stream using hybrid encryption (symmetric + RSA).
|
|
|
380
539
|
|
|
381
540
|
<details>
|
|
382
541
|
|
|
383
|
-
<summary>Returns</summary>
|
|
542
|
+
<summary style="cursor:pointer">Returns</summary>
|
|
384
543
|
|
|
385
|
-
Type: `
|
|
544
|
+
Type: `Promise<void>`
|
|
386
545
|
|
|
387
|
-
|
|
388
|
-
- a new instance of `cipher` allowing you to add listeners to the `cipher` encryption process.
|
|
389
|
-
- the actual `encrypt` callback that must be called and awaited to start the encryption process.
|
|
546
|
+
A new Promise that resolves `void` once stream encryption is completed.
|
|
390
547
|
|
|
391
548
|
</details>
|
|
392
549
|
|
|
393
550
|
---
|
|
394
551
|
|
|
395
|
-
- See [
|
|
396
|
-
- See [`Cph.Stream.Hybrid.EncryptOptions`](#cphstreamhybridStreamEncryptoptions) for more informations about encryption options.
|
|
397
|
-
- See [In-memory data stream with hybrid encryption/decryption](#in-memory-data-stream-with-hybrid-encryptiondecryption) examples.
|
|
398
|
-
- See [File based data stream with hybrid encryption/decryption](#file-based-data-stream-with-hybrid-encryptiondecryption) examples.
|
|
552
|
+
- See [In-memory data stream encryption/decryption](#in-memory-data-stream-encryptiondecryption) example.
|
|
399
553
|
|
|
400
554
|
---
|
|
401
555
|
|
|
402
|
-
##### `Cipher.
|
|
556
|
+
##### `Cipher.stream.Decrypt()`
|
|
403
557
|
|
|
404
|
-
|
|
558
|
+
Decrypt stream data.
|
|
405
559
|
|
|
406
560
|
<details>
|
|
407
561
|
|
|
408
562
|
<summary>Parameters</summary>
|
|
409
563
|
|
|
410
|
-
| Name
|
|
411
|
-
|
|
|
412
|
-
| `
|
|
413
|
-
| `options`
|
|
564
|
+
| Name | Type | Default | Description |
|
|
565
|
+
| ------------------- | --------------------------- | ------------- | ------------------------------------------------------ |
|
|
566
|
+
| `secret` | `CoerceToUint8ArrayInput` | - | The secret key used to decrypt the data. |
|
|
567
|
+
| `options` | `Cph.Stream.DecryptOptions` | - | An object defining required options. |
|
|
568
|
+
| `options.input` | `Readable` | - | The `Readable` Stream where encrypted data is read. |
|
|
569
|
+
| `options.output` | `Writable` | - | The `Writable` Stream where decrypted data is written. |
|
|
570
|
+
| `options.algorithm` | `Cph.CBCTypes` | `aes-256-cbc` | One of the Cipher Block Chaining algorithm. |
|
|
571
|
+
|
|
572
|
+
</details>
|
|
573
|
+
|
|
574
|
+
---
|
|
575
|
+
|
|
576
|
+
<details>
|
|
577
|
+
|
|
578
|
+
<summary style="cursor:pointer">Returns</summary>
|
|
579
|
+
|
|
580
|
+
Type: `Promise<void>`
|
|
581
|
+
|
|
582
|
+
A new Promise that resolves `void` once stream decryption is completed.
|
|
583
|
+
|
|
584
|
+
</details>
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
|
|
588
|
+
- See [In-memory data stream encryption/decryption](#in-memory-data-stream-encryptiondecryption) example.
|
|
589
|
+
|
|
590
|
+
---
|
|
591
|
+
|
|
592
|
+
##### `Cipher.stream.HybridEncrypt()`
|
|
593
|
+
|
|
594
|
+
Encrypt stream data using hybrid encryption.
|
|
595
|
+
|
|
596
|
+
> [!WARNING]
|
|
597
|
+
> Please, note that when using hybrid encryption/decryption algorithms:
|
|
598
|
+
>
|
|
599
|
+
> - an RSA keypair is required.
|
|
600
|
+
> - if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or `chacha20-poly1305` algorithm:
|
|
601
|
+
> - aes-128-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
602
|
+
> - aes-192-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
603
|
+
> - aes-256-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
604
|
+
> - chacha20-poly1305 (`type` can only be `pkcs1`)
|
|
605
|
+
|
|
606
|
+
<details>
|
|
607
|
+
|
|
608
|
+
<summary style="cursor:pointer">Parameters</summary>
|
|
609
|
+
|
|
610
|
+
| Parameter | Type | Default | Description |
|
|
611
|
+
| ------------------- | --------------------------- | ------------- | -------------------------------------------------------- |
|
|
612
|
+
| `key` | `crypto.KeyLike` | - | The RSA Public Key. |
|
|
613
|
+
| `options` | `Cph.Stream.EncryptOptions` | - | An object defining required options. |
|
|
614
|
+
| `options.input` | `Readable` | - | The `Readable` Stream where raw data to encrypt is read. |
|
|
615
|
+
| `options.output` | `Writable` | - | The `Writable` Stream where encrypted data is written. |
|
|
616
|
+
| `options.algorithm` | `Cph.CBCTypes` | `aes-256-cbc` | One of the Cipher Block Chaining algorithm. |
|
|
617
|
+
|
|
618
|
+
</details>
|
|
619
|
+
|
|
620
|
+
---
|
|
621
|
+
|
|
622
|
+
<details>
|
|
623
|
+
|
|
624
|
+
<summary>Returns</summary>
|
|
625
|
+
|
|
626
|
+
Type: `Promise<void>`
|
|
627
|
+
|
|
628
|
+
A new Promise that resolves `void` once stream encryption is completed.
|
|
629
|
+
|
|
630
|
+
</details>
|
|
631
|
+
|
|
632
|
+
---
|
|
633
|
+
|
|
634
|
+
- See [In-memory data stream with hybrid encryption/decryption](#in-memory-data-stream-with-hybrid-encryptiondecryption) example.
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
##### `Cipher.stream.HybridDecrypt()`
|
|
639
|
+
|
|
640
|
+
Decrypt stream data using hybrid decryption.
|
|
641
|
+
|
|
642
|
+
> [!WARNING]
|
|
643
|
+
> Please, note that when using hybrid encryption/decryption algorithms:
|
|
644
|
+
>
|
|
645
|
+
> - an RSA keypair is required.
|
|
646
|
+
> - if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or `chacha20-poly1305` algorithm:
|
|
647
|
+
> - aes-128-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
648
|
+
> - aes-192-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
649
|
+
> - aes-256-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
650
|
+
> - chacha20-poly1305 (`type` can only be `pkcs1`)
|
|
651
|
+
|
|
652
|
+
<details>
|
|
653
|
+
|
|
654
|
+
<summary style="cursor:pointer">Parameters</summary>
|
|
655
|
+
|
|
656
|
+
| Parameter | Type | Default | Description |
|
|
657
|
+
| ------------------- | --------------------------- | ------------- | ------------------------------------------------------ |
|
|
658
|
+
| `key` | `Cph.PrivateKey` | - | The RSA Private Key. |
|
|
659
|
+
| `options` | `Cph.Stream.DecryptOptions` | - | An object defining required options. |
|
|
660
|
+
| `options.input` | `Readable` | - | The `Readable` Stream where encrypted data is read. |
|
|
661
|
+
| `options.output` | `Writable` | - | The `Writable` Stream where decrypted data is written. |
|
|
662
|
+
| `options.algorithm` | `Cph.CBCTypes` | `aes-256-cbc` | One of the Cipher Block Chaining algorithm. |
|
|
414
663
|
|
|
415
664
|
</details>
|
|
416
665
|
|
|
@@ -420,19 +669,17 @@ Decrypts a stream using hybrid decryption (symmetric + RSA).
|
|
|
420
669
|
|
|
421
670
|
<summary>Returns</summary>
|
|
422
671
|
|
|
423
|
-
Type: `Promise<
|
|
672
|
+
Type: `Promise<void>`
|
|
424
673
|
|
|
425
|
-
|
|
426
|
-
- a new instance of `crypto.Decipheriv` allowing you to add listeners to the `decipher` decryption process.
|
|
427
|
-
- the actual `decrypt` callback that must be called and awaited in order to start the decryption process.
|
|
674
|
+
A new Promise that resolves `void` once stream encryption is completed.
|
|
428
675
|
|
|
429
676
|
</details>
|
|
430
677
|
|
|
431
678
|
---
|
|
432
679
|
|
|
433
|
-
- See [`
|
|
434
|
-
- See [
|
|
435
|
-
- See [
|
|
680
|
+
- See [`CoerceToUint8ArrayInput`](#coercetouint8arrayinput) for more informations about supported input data types.
|
|
681
|
+
- See [`Cph.PrivateKey`](#cphprivatekey) for accepted formats.
|
|
682
|
+
- See [In-memory data stream with hybrid encryption/decryption](#in-memory-data-stream-with-hybrid-encryptiondecryption) example.
|
|
436
683
|
|
|
437
684
|
---
|
|
438
685
|
|
|
@@ -448,13 +695,13 @@ This module supports different input data types and it uses the [`coerceToUint8A
|
|
|
448
695
|
|
|
449
696
|
##### `Cph.CBCTypes`
|
|
450
697
|
|
|
451
|
-
Cipher
|
|
698
|
+
AES Cipher Block Chaining algorithms.
|
|
452
699
|
|
|
453
700
|
---
|
|
454
701
|
|
|
455
702
|
##### `Cph.AesAlgorithm`
|
|
456
703
|
|
|
457
|
-
|
|
704
|
+
All supported AES algorithms.
|
|
458
705
|
|
|
459
706
|
---
|
|
460
707
|
|
|
@@ -491,143 +738,127 @@ Common options in encryption/decryption processes.
|
|
|
491
738
|
|
|
492
739
|
---
|
|
493
740
|
|
|
494
|
-
##### `Cph.Stream.
|
|
741
|
+
##### `Cph.Stream.EncryptOptions`
|
|
495
742
|
|
|
496
743
|
Stream symmetric encryption options.
|
|
497
744
|
|
|
498
|
-
- Extends [`Cph.Options<Cph.CBCTypes>`](#cphoptionst).
|
|
499
|
-
|
|
500
745
|
<details>
|
|
501
746
|
|
|
502
747
|
<summary>Properties</summary>
|
|
503
748
|
|
|
504
|
-
| Property
|
|
505
|
-
|
|
|
506
|
-
| `input`
|
|
507
|
-
| `output`
|
|
749
|
+
| Property | Type | Description |
|
|
750
|
+
| ----------- | -------------- | ------------------------------------------------------------- |
|
|
751
|
+
| `input` | `Readable` | The `Readable` Stream from where raw data to encrypt is read. |
|
|
752
|
+
| `output` | `Writable` | The `Writable` Stream where encrypted data is written. |
|
|
753
|
+
| `algorithm` | `Cph.CBCTypes` | One of the Cipher Block Chaining algorithm. |
|
|
508
754
|
|
|
509
755
|
</details>
|
|
510
756
|
|
|
511
757
|
---
|
|
512
758
|
|
|
513
|
-
##### `Cph.Stream.
|
|
514
|
-
|
|
515
|
-
Returnign object from `Cipher.streamEncrypt()` method.
|
|
516
|
-
|
|
517
|
-
<details>
|
|
518
|
-
|
|
519
|
-
<summary>Properties</summary>
|
|
520
|
-
|
|
521
|
-
| Property | Type | Description |
|
|
522
|
-
| --------- | --------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
523
|
-
| `cipher` | `crypto.Cipheriv` | The `crypto.Cipheriv` instance. |
|
|
524
|
-
| `encrypt` | `() => Promise<void>` | The actual `encrypt` callback that must be called and awaited in order to start the encryption process. |
|
|
525
|
-
|
|
526
|
-
</details>
|
|
527
|
-
|
|
528
|
-
---
|
|
529
|
-
|
|
530
|
-
##### `Cph.Stream.Symmetric.DecryptOptions`
|
|
759
|
+
##### `Cph.Stream.DecryptOptions`
|
|
531
760
|
|
|
532
761
|
Stream symmetric decryption options.
|
|
533
762
|
|
|
534
|
-
-
|
|
763
|
+
- Alias of [`Cph.Stream.EncryptOptions`](#cphstreamencryptoptions).
|
|
535
764
|
|
|
536
765
|
<details>
|
|
537
766
|
|
|
538
767
|
<summary>Properties</summary>
|
|
539
768
|
|
|
540
|
-
| Property
|
|
541
|
-
|
|
|
542
|
-
| `input`
|
|
543
|
-
| `output`
|
|
769
|
+
| Property | Type | Description |
|
|
770
|
+
| ----------- | -------------- | -------------------------------------------------------- |
|
|
771
|
+
| `input` | `Readable` | The `Readable` Stream from where encrypted data is read. |
|
|
772
|
+
| `output` | `Writable` | The `Writable` Stream where decrypted data is written. |
|
|
773
|
+
| `algorithm` | `Cph.CBCTypes` | One of the Cipher Block Chaining algorithm. |
|
|
544
774
|
|
|
545
775
|
</details>
|
|
546
776
|
|
|
547
777
|
---
|
|
548
778
|
|
|
549
|
-
##### `Cph.
|
|
550
|
-
|
|
551
|
-
Returnign object from awaited `Cipher.streamDecrypt()` method.
|
|
552
|
-
|
|
553
|
-
<details>
|
|
779
|
+
##### `Cph.PrivateKey`
|
|
554
780
|
|
|
555
|
-
|
|
781
|
+
The RSA Private Key.
|
|
556
782
|
|
|
557
|
-
|
|
558
|
-
| ---------- | --------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
559
|
-
| `decipher` | `crypto.Decipheriv` | The `crypto.Decipheriv` instance. |
|
|
560
|
-
| `decrypt` | `() => Promise<void>` | The actual `decrypt` callback that must be called and awaited in order to start the decryption process. |
|
|
783
|
+
It could be:
|
|
561
784
|
|
|
562
|
-
|
|
785
|
+
- a `crypto.KeyLike`
|
|
786
|
+
- an object defining `key` and `passphrase` where `key` is a `crypto.KeyLike`
|
|
563
787
|
|
|
564
788
|
---
|
|
565
789
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
Stream hybrid encryption options.
|
|
790
|
+
### Examples
|
|
569
791
|
|
|
570
|
-
-
|
|
792
|
+
#### In-memory data buffer encryption/decryption
|
|
571
793
|
|
|
572
|
-
|
|
794
|
+
The simpliest way to encrypt/decrypt in-memory data buffers.
|
|
573
795
|
|
|
574
|
-
|
|
796
|
+
```ts
|
|
797
|
+
// encrypt
|
|
798
|
+
const data = "my top-secret data";
|
|
799
|
+
const password = "my-very-strong-password";
|
|
575
800
|
|
|
576
|
-
|
|
801
|
+
const encrypted = Cipher.Encrypt(data, password);
|
|
577
802
|
|
|
578
|
-
|
|
803
|
+
// decrypt
|
|
804
|
+
const decrypted = Cipher.Decrypt(encrypted, password);
|
|
805
|
+
console.log(decrypted); // Outputs: my top-secret data
|
|
806
|
+
```
|
|
579
807
|
|
|
580
808
|
---
|
|
581
809
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
Stream hybrid decryption options.
|
|
585
|
-
|
|
586
|
-
- Extends [`Cph.Stream.Symmetric.DecryptOptions`](#cphstreamsymmetricdecryptoptions).
|
|
587
|
-
|
|
588
|
-
<details>
|
|
589
|
-
|
|
590
|
-
<summary>Properties</summary>
|
|
810
|
+
#### In-memory data buffer hybrid encryption/decryption
|
|
591
811
|
|
|
592
|
-
|
|
593
|
-
| -------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
594
|
-
| `rsaKeyLength` | `number` | The RSA key length in bytes used while encrypting data. This is used to properly extract the encrypted Cipher Key and Initialization Vector from the encrypted data. |
|
|
812
|
+
Hybrid encryption offers an higher level of security since only the RSA Private Key owner will be able to decrypt the data.
|
|
595
813
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
814
|
+
> [!WARNING]
|
|
815
|
+
> Please, note that when using hybrid encryption/decryption algorithms:
|
|
816
|
+
>
|
|
817
|
+
> - an RSA keypair is required.
|
|
818
|
+
> - if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or `chacha20-poly1305` algorithm:
|
|
819
|
+
> - aes-128-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
820
|
+
> - aes-192-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
821
|
+
> - aes-256-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
822
|
+
> - chacha20-poly1305 (`type` can only be `pkcs1`)
|
|
599
823
|
|
|
600
|
-
#####
|
|
601
|
-
|
|
602
|
-
Returnign object from awaited `Cipher.hybridStreamDecrypt()` method.
|
|
824
|
+
##### Keypair
|
|
603
825
|
|
|
604
|
-
|
|
826
|
+
```ts
|
|
827
|
+
import { Cipher } from "@alessiofrittoli/crypto-cipher";
|
|
605
828
|
|
|
606
|
-
|
|
829
|
+
const keyPair = crypto.generateKeyPairSync("rsa", {
|
|
830
|
+
modulusLength: 512 * 8, // 4096 bits
|
|
831
|
+
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
832
|
+
privateKeyEncoding: { type: "pkcs1", format: "pem" },
|
|
833
|
+
});
|
|
607
834
|
|
|
608
|
-
|
|
835
|
+
// or you can optionally set a custom passphrase
|
|
836
|
+
const passphrase = "custompassphrase";
|
|
609
837
|
|
|
610
|
-
|
|
838
|
+
const keyPair = crypto.generateKeyPairSync("rsa", {
|
|
839
|
+
modulusLength: 512 * 8, // 4096 bits
|
|
840
|
+
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
841
|
+
privateKeyEncoding: {
|
|
842
|
+
type: "pkcs1",
|
|
843
|
+
format: "pem",
|
|
844
|
+
passphrase,
|
|
845
|
+
cipher: Cipher.ALGORITHM.CHACHA_20_POLY,
|
|
846
|
+
},
|
|
847
|
+
});
|
|
848
|
+
```
|
|
611
849
|
|
|
612
850
|
```ts
|
|
613
851
|
import { Cipher } from "@alessiofrittoli/crypto-cipher";
|
|
614
|
-
import type { Cph as CipherTypes } from "@alessiofrittoli/crypto-cipher/types";
|
|
615
|
-
```
|
|
616
|
-
|
|
617
|
-
#### In-memory data buffer encryption/decryption
|
|
618
852
|
|
|
619
|
-
The simpliest way to encrypt/decrypt in-memory data buffers.
|
|
620
|
-
|
|
621
|
-
```ts
|
|
622
853
|
// encrypt
|
|
623
854
|
const data = "my top-secret data";
|
|
624
|
-
const
|
|
625
|
-
|
|
626
|
-
const encrypted = Cipher.encrypt(data, password);
|
|
855
|
+
const encrypted = Cipher.HybridEncrypt(data, keypair.publicKey);
|
|
627
856
|
|
|
628
857
|
// decrypt
|
|
629
|
-
const decrypted = Cipher.
|
|
630
|
-
|
|
858
|
+
const decrypted = Cipher.HybridDecrypt(encrypted, {
|
|
859
|
+
key: keypair.privateKey,
|
|
860
|
+
passphrase,
|
|
861
|
+
});
|
|
631
862
|
```
|
|
632
863
|
|
|
633
864
|
---
|
|
@@ -642,38 +873,40 @@ The in-memory data stream comes pretty handy when, for example, we need to strea
|
|
|
642
873
|
// /api/stream-encrypt
|
|
643
874
|
|
|
644
875
|
import { Readable, Writable } from "stream";
|
|
876
|
+
import { Stream } from "@alessiofrittoli/stream-writer";
|
|
645
877
|
|
|
646
878
|
const routeHandler = () => {
|
|
647
|
-
const data = "my top-secret data";
|
|
648
879
|
const password = "my-very-strong-password";
|
|
649
|
-
const stream = new
|
|
650
|
-
const
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
});
|
|
880
|
+
const stream = new Stream();
|
|
881
|
+
const headers = new Headers(stream.headers);
|
|
882
|
+
|
|
883
|
+
const input = Readable.from([
|
|
884
|
+
Buffer.from("Chunk n.1"),
|
|
885
|
+
Buffer.from("Chunk n.2"),
|
|
886
|
+
Buffer.from("Chunk n.3"),
|
|
887
|
+
Buffer.from("Chunk n.4"),
|
|
888
|
+
]);
|
|
659
889
|
|
|
660
890
|
// `Writable` Stream where encrypted data is written
|
|
661
891
|
const output = new Writable({
|
|
662
|
-
write(chunk, encoding, callback) {
|
|
663
|
-
|
|
892
|
+
async write(chunk, encoding, callback) {
|
|
893
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
894
|
+
await stream.write(chunk);
|
|
664
895
|
callback();
|
|
665
896
|
},
|
|
666
|
-
final(callback) {
|
|
667
|
-
|
|
897
|
+
async final(callback) {
|
|
898
|
+
await stream.close();
|
|
668
899
|
callback();
|
|
669
900
|
},
|
|
670
901
|
});
|
|
671
902
|
|
|
672
|
-
Cipher.
|
|
903
|
+
Cipher.stream.Encrypt(password, { input, output }).catch(async () => {
|
|
904
|
+
await stream.close();
|
|
905
|
+
});
|
|
673
906
|
|
|
674
907
|
return (
|
|
675
908
|
// encrypted stream
|
|
676
|
-
new Response(stream.readable)
|
|
909
|
+
new Response(stream.readable, { headers })
|
|
677
910
|
);
|
|
678
911
|
};
|
|
679
912
|
```
|
|
@@ -684,6 +917,7 @@ const routeHandler = () => {
|
|
|
684
917
|
// /api/stream-decrypt
|
|
685
918
|
|
|
686
919
|
import { Transform, Writable } from "stream";
|
|
920
|
+
import { Cipher } from "@alessiofrittoli/crypto-cipher";
|
|
687
921
|
import { StreamReader } from "@alessiofrittoli/stream-reader";
|
|
688
922
|
|
|
689
923
|
const password = "my-very-strong-password";
|
|
@@ -694,39 +928,46 @@ const routeHandler = () =>
|
|
|
694
928
|
return new Respone(null, { status: 400 });
|
|
695
929
|
}
|
|
696
930
|
|
|
697
|
-
|
|
698
|
-
const
|
|
699
|
-
|
|
700
|
-
|
|
931
|
+
// web stream where decrypted data is written
|
|
932
|
+
const stream = new Stream<Buffer, string>({
|
|
933
|
+
transform(chunk, controller) {
|
|
934
|
+
controller.enqueue(chunk.toString());
|
|
935
|
+
},
|
|
936
|
+
});
|
|
937
|
+
const headers = new Headers(stream.headers);
|
|
701
938
|
|
|
702
|
-
|
|
939
|
+
headers.set("Content-Type", "text/html");
|
|
703
940
|
|
|
704
|
-
reader
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
reader.on("close", () => {
|
|
708
|
-
input.push(null);
|
|
941
|
+
const reader = new StreamReader<Uint8Array, Buffer, false>(response.body, {
|
|
942
|
+
inMemory: false,
|
|
943
|
+
transform: Buffer.from,
|
|
709
944
|
});
|
|
710
945
|
|
|
946
|
+
const input = new Transform();
|
|
947
|
+
|
|
948
|
+
reader.on("data", (chunk) => input.push(chunk));
|
|
949
|
+
reader.on("close", () => input.end());
|
|
950
|
+
|
|
951
|
+
reader.read();
|
|
952
|
+
|
|
953
|
+
// `Writable` Stream where encrypted data is written
|
|
711
954
|
const output = new Writable({
|
|
712
|
-
write(chunk, encoding, callback) {
|
|
713
|
-
|
|
955
|
+
async write(chunk: Buffer, encoding, callback) {
|
|
956
|
+
await stream.write(chunk);
|
|
714
957
|
callback();
|
|
715
958
|
},
|
|
716
959
|
final(callback) {
|
|
717
|
-
|
|
960
|
+
stream.close();
|
|
718
961
|
callback();
|
|
719
962
|
},
|
|
720
963
|
});
|
|
721
964
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
965
|
+
Cipher.stream.Decrypt(password, { input, output }).catch(async (error) => {
|
|
966
|
+
console.error(error);
|
|
967
|
+
await stream.close();
|
|
968
|
+
});
|
|
725
969
|
|
|
726
|
-
return (
|
|
727
|
-
// decrypted stream
|
|
728
|
-
new Response(stream.readable)
|
|
729
|
-
);
|
|
970
|
+
return new Response(stream.readable, { headers });
|
|
730
971
|
});
|
|
731
972
|
```
|
|
732
973
|
|
|
@@ -734,30 +975,40 @@ const routeHandler = () =>
|
|
|
734
975
|
|
|
735
976
|
#### In-memory data stream with hybrid encryption/decryption
|
|
736
977
|
|
|
737
|
-
Hybrid encryption offers an higher level of security
|
|
978
|
+
Hybrid encryption offers an higher level of security since only the RSA Private Key owner will be able to decrypt the data.
|
|
979
|
+
|
|
980
|
+
> [!WARNING]
|
|
981
|
+
> Please, note that when using hybrid encryption/decryption algorithms:
|
|
982
|
+
>
|
|
983
|
+
> - an RSA keypair is required.
|
|
984
|
+
> - if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or `chacha20-poly1305` algorithm:
|
|
985
|
+
> - aes-128-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
986
|
+
> - aes-192-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
987
|
+
> - aes-256-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
988
|
+
> - chacha20-poly1305 (`type` can only be `pkcs1`)
|
|
738
989
|
|
|
739
990
|
##### Keypair
|
|
740
991
|
|
|
741
992
|
```ts
|
|
742
|
-
|
|
993
|
+
import { Cipher } from "@alessiofrittoli/crypto-cipher";
|
|
743
994
|
|
|
744
|
-
/** RSA modulus length is required for proper key extraction during decryption process. */
|
|
745
|
-
const rsaKeyLength = 512; // bytes
|
|
746
995
|
const keyPair = crypto.generateKeyPairSync("rsa", {
|
|
747
|
-
modulusLength:
|
|
996
|
+
modulusLength: 512 * 8, // 4096 bits
|
|
748
997
|
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
749
998
|
privateKeyEncoding: { type: "pkcs1", format: "pem" },
|
|
750
999
|
});
|
|
751
1000
|
|
|
752
1001
|
// or you can optionally set a custom passphrase
|
|
1002
|
+
const passphrase = "custompassphrase";
|
|
1003
|
+
|
|
753
1004
|
const keyPair = crypto.generateKeyPairSync("rsa", {
|
|
754
|
-
modulusLength:
|
|
1005
|
+
modulusLength: 512 * 8, // 4096 bits
|
|
755
1006
|
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
756
1007
|
privateKeyEncoding: {
|
|
757
1008
|
type: "pkcs1",
|
|
758
1009
|
format: "pem",
|
|
759
|
-
passphrase
|
|
760
|
-
cipher:
|
|
1010
|
+
passphrase,
|
|
1011
|
+
cipher: Cipher.ALGORITHM.CHACHA_20_POLY,
|
|
761
1012
|
},
|
|
762
1013
|
});
|
|
763
1014
|
```
|
|
@@ -786,17 +1037,7 @@ const output = new Writable({
|
|
|
786
1037
|
},
|
|
787
1038
|
});
|
|
788
1039
|
|
|
789
|
-
|
|
790
|
-
password,
|
|
791
|
-
{
|
|
792
|
-
key: keyPair.publicKey,
|
|
793
|
-
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
|
794
|
-
oaepHash: "SHA-256",
|
|
795
|
-
},
|
|
796
|
-
{ input, output }
|
|
797
|
-
);
|
|
798
|
-
|
|
799
|
-
await encrypt();
|
|
1040
|
+
await Cipher.stream.HybridEncrypt(keyPair.publicKey, { input, output });
|
|
800
1041
|
```
|
|
801
1042
|
|
|
802
1043
|
---
|
|
@@ -807,12 +1048,7 @@ await encrypt();
|
|
|
807
1048
|
/** Store decrypted chunks. */
|
|
808
1049
|
const chunks: Buffer[] = [];
|
|
809
1050
|
// Create a `Readable` Stream with encrypted data.
|
|
810
|
-
const input =
|
|
811
|
-
read() {
|
|
812
|
-
this.push(Buffer.concat(encryptedChunks)); // Push data to decrypt
|
|
813
|
-
this.push(null); // Signal end of stream
|
|
814
|
-
},
|
|
815
|
-
});
|
|
1051
|
+
const input = Readable.from(encryptedChunks);
|
|
816
1052
|
|
|
817
1053
|
// Create a `Writable` Stream where decrypted data is written
|
|
818
1054
|
const output = new Writable({
|
|
@@ -822,18 +1058,14 @@ const output = new Writable({
|
|
|
822
1058
|
},
|
|
823
1059
|
});
|
|
824
1060
|
|
|
825
|
-
|
|
1061
|
+
await Cipher.stream.HybridDecrypt(
|
|
826
1062
|
{
|
|
827
1063
|
key: keyPair.privateKey,
|
|
828
|
-
passphrase
|
|
829
|
-
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
|
830
|
-
oaepHash: "SHA-256",
|
|
1064
|
+
passphrase, // optional passhrase (required if set while generating keypair).
|
|
831
1065
|
},
|
|
832
|
-
{ input, output
|
|
1066
|
+
{ input, output }
|
|
833
1067
|
);
|
|
834
1068
|
|
|
835
|
-
await decrypt();
|
|
836
|
-
|
|
837
1069
|
console.log(Buffer.concat(chunks).toString()); // Outputs: 'my top-secret data'
|
|
838
1070
|
```
|
|
839
1071
|
|
|
@@ -855,7 +1087,7 @@ const input = fs.createReadStream("my-very-large-top-secret-file.pdf");
|
|
|
855
1087
|
// output where encrypted data is written
|
|
856
1088
|
const output = fs.createWriteStream("my-very-large-top-secret-file.encrypted");
|
|
857
1089
|
// encrypt
|
|
858
|
-
await Cipher.
|
|
1090
|
+
await Cipher.stream.Encrypt(password, { input, output });
|
|
859
1091
|
```
|
|
860
1092
|
|
|
861
1093
|
---
|
|
@@ -874,8 +1106,7 @@ const output = fs.createWriteStream(
|
|
|
874
1106
|
"my-very-large-top-secret-file-decrypted.pdf"
|
|
875
1107
|
);
|
|
876
1108
|
// decrypt
|
|
877
|
-
|
|
878
|
-
await decrypt();
|
|
1109
|
+
await Cipher.stream.Decrypt(password, { input, output });
|
|
879
1110
|
```
|
|
880
1111
|
|
|
881
1112
|
---
|
|
@@ -884,28 +1115,38 @@ await decrypt();
|
|
|
884
1115
|
|
|
885
1116
|
Nothig differs from the [In-memory data stream with hybrid encryption/decryption](#in-memory-data-stream-with-hybrid-encryptiondecryption) example, except for `input` and `output` streams which now comes directly from files reading/writing.
|
|
886
1117
|
|
|
1118
|
+
> [!WARNING]
|
|
1119
|
+
> Please, note that when using hybrid encryption/decryption algorithms:
|
|
1120
|
+
>
|
|
1121
|
+
> - an RSA keypair is required.
|
|
1122
|
+
> - if a passphrase is set for the Private Key, please make sure to use one of the Cipher Block Chaining algorithm or `chacha20-poly1305` algorithm:
|
|
1123
|
+
> - aes-128-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
1124
|
+
> - aes-192-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
1125
|
+
> - aes-256-cbc (`type` can be `pkcs1` or `pkcs8`)
|
|
1126
|
+
> - chacha20-poly1305 (`type` can only be `pkcs1`)
|
|
1127
|
+
|
|
887
1128
|
##### Keypair
|
|
888
1129
|
|
|
889
1130
|
```ts
|
|
890
|
-
|
|
1131
|
+
import { Cipher } from "@alessiofrittoli/crypto-cipher";
|
|
891
1132
|
|
|
892
|
-
/** RSA modulus length is required for proper key extraction during decryption process. */
|
|
893
|
-
const rsaKeyLength = 512; // bytes
|
|
894
1133
|
const keyPair = crypto.generateKeyPairSync("rsa", {
|
|
895
|
-
modulusLength:
|
|
1134
|
+
modulusLength: 512 * 8, // 4096 bits
|
|
896
1135
|
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
897
1136
|
privateKeyEncoding: { type: "pkcs1", format: "pem" },
|
|
898
1137
|
});
|
|
899
1138
|
|
|
900
1139
|
// or you can optionally set a custom passphrase
|
|
1140
|
+
const passphrase = "custompassphrase";
|
|
1141
|
+
|
|
901
1142
|
const keyPair = crypto.generateKeyPairSync("rsa", {
|
|
902
|
-
modulusLength:
|
|
1143
|
+
modulusLength: 512 * 8, // 4096 bits
|
|
903
1144
|
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
904
1145
|
privateKeyEncoding: {
|
|
905
1146
|
type: "pkcs1",
|
|
906
1147
|
format: "pem",
|
|
907
|
-
passphrase
|
|
908
|
-
cipher:
|
|
1148
|
+
passphrase,
|
|
1149
|
+
cipher: Cipher.ALGORITHM.CHACHA_20_POLY,
|
|
909
1150
|
},
|
|
910
1151
|
});
|
|
911
1152
|
```
|
|
@@ -915,23 +1156,12 @@ const keyPair = crypto.generateKeyPairSync("rsa", {
|
|
|
915
1156
|
```ts
|
|
916
1157
|
import fs from "fs";
|
|
917
1158
|
|
|
918
|
-
const password = "my-very-strong-password";
|
|
919
|
-
|
|
920
1159
|
// input where raw data to encrypt is read
|
|
921
1160
|
const input = fs.createReadStream("my-very-large-top-secret-file.pdf");
|
|
922
1161
|
// output where encrypted data is written
|
|
923
1162
|
const output = fs.createWriteStream("my-very-large-top-secret-file.encrypted");
|
|
924
1163
|
// encrypt
|
|
925
|
-
|
|
926
|
-
password,
|
|
927
|
-
{
|
|
928
|
-
key: keyPair.publicKey,
|
|
929
|
-
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
|
930
|
-
oaepHash: "SHA-256",
|
|
931
|
-
},
|
|
932
|
-
{ input, output }
|
|
933
|
-
);
|
|
934
|
-
await encrypt();
|
|
1164
|
+
await Cipher.stream.HybridEncrypt(keyPair.publicKey, { input, output });
|
|
935
1165
|
```
|
|
936
1166
|
|
|
937
1167
|
---
|
|
@@ -941,8 +1171,6 @@ await encrypt();
|
|
|
941
1171
|
```ts
|
|
942
1172
|
import fs from "fs";
|
|
943
1173
|
|
|
944
|
-
const password = "my-very-strong-password";
|
|
945
|
-
|
|
946
1174
|
// input where encrypted data is read
|
|
947
1175
|
const input = fs.createReadStream("my-very-large-top-secret-file.encrypted");
|
|
948
1176
|
// output where decrypted data is written
|
|
@@ -950,14 +1178,12 @@ const output = fs.createWriteStream(
|
|
|
950
1178
|
"my-very-large-top-secret-file-decrypted.pdf"
|
|
951
1179
|
);
|
|
952
1180
|
// decrypt
|
|
953
|
-
const { decrypt } = await Cipher.
|
|
1181
|
+
const { decrypt } = await Cipher.stream.HybridDecrypt(
|
|
954
1182
|
{
|
|
955
1183
|
key: keyPair.privateKey,
|
|
956
|
-
passphrase
|
|
957
|
-
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
|
958
|
-
oaepHash: "SHA-256",
|
|
1184
|
+
passphrase, // optional passhrase (required if set while generating keypair).
|
|
959
1185
|
},
|
|
960
|
-
{ input, output
|
|
1186
|
+
{ input, output }
|
|
961
1187
|
);
|
|
962
1188
|
```
|
|
963
1189
|
|