@alessiofrittoli/crypto-cipher 1.1.0 → 2.1.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 +122 -52
- package/dist/index.d.mts +17 -9
- package/dist/index.d.ts +17 -9
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -0
- package/dist/types.d.mts +28 -2
- package/dist/types.d.ts +28 -2
- package/dist/types.js +2 -1
- package/dist/types.js.map +1 -0
- package/dist/types.mjs +2 -0
- package/dist/types.mjs.map +1 -0
- package/package.json +35 -15
package/README.md
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
# Crypto Cipher 🔐
|
|
2
2
|
|
|
3
|
-
[![NPM Latest Version][version-badge]][npm-url] [![Coverage Status][coverage-badge]][coverage-url] [![NPM Monthly Downloads][downloads-badge]][npm-url] [![Dependencies][deps-badge]][deps-url]
|
|
3
|
+
[![NPM Latest Version][version-badge]][npm-url] [![Coverage Status][coverage-badge]][coverage-url] [![Socket Status][socket-badge]][socket-url] [![NPM Monthly Downloads][downloads-badge]][npm-url] [![Dependencies][deps-badge]][deps-url]
|
|
4
|
+
|
|
5
|
+
[![GitHub Sponsor][sponsor-badge]][sponsor-url]
|
|
4
6
|
|
|
5
7
|
[version-badge]: https://img.shields.io/npm/v/%40alessiofrittoli%2Fcrypto-cipher
|
|
6
8
|
[npm-url]: https://npmjs.org/package/%40alessiofrittoli%2Fcrypto-cipher
|
|
7
9
|
[coverage-badge]: https://coveralls.io/repos/github/alessiofrittoli/crypto-cipher/badge.svg
|
|
8
10
|
[coverage-url]: https://coveralls.io/github/alessiofrittoli/crypto-cipher
|
|
11
|
+
[socket-badge]: https://socket.dev/api/badge/npm/package/@alessiofrittoli/crypto-cipher
|
|
12
|
+
[socket-url]: https://socket.dev/npm/package/@alessiofrittoli/crypto-cipher/overview
|
|
9
13
|
[downloads-badge]: https://img.shields.io/npm/dm/%40alessiofrittoli%2Fcrypto-cipher.svg
|
|
10
14
|
[deps-badge]: https://img.shields.io/librariesio/release/npm/%40alessiofrittoli%2Fcrypto-cipher
|
|
11
15
|
[deps-url]: https://libraries.io/npm/%40alessiofrittoli%2Fcrypto-cipher
|
|
12
16
|
|
|
17
|
+
[sponsor-badge]: https://img.shields.io/static/v1?label=Fund%20this%20package&message=%E2%9D%A4&logo=GitHub&color=%23DB61A2
|
|
18
|
+
[sponsor-url]: https://github.com/sponsors/alessiofrittoli
|
|
19
|
+
|
|
13
20
|
## Node.js Cipher cryptograph utility library
|
|
14
21
|
|
|
15
22
|
### Table of Contents
|
|
@@ -299,9 +306,11 @@ Encrypts a `Readable` stream to a `Writable` stream.
|
|
|
299
306
|
|
|
300
307
|
<summary>Returns</summary>
|
|
301
308
|
|
|
302
|
-
Type: `
|
|
309
|
+
Type: `Cph.Stream.Symmetric.EncryptReturnType`
|
|
303
310
|
|
|
304
|
-
-
|
|
311
|
+
- An object containing:
|
|
312
|
+
- a new instance of `crypto.Cipher` allowing you to add listeners to the `cipher` encryption process.
|
|
313
|
+
- the actual `encrypt` callback that must be called and awaited in order to start the encryption process.
|
|
305
314
|
|
|
306
315
|
</details>
|
|
307
316
|
|
|
@@ -335,9 +344,11 @@ Decrypts a `Readable` stream to a `Writable` stream.
|
|
|
335
344
|
|
|
336
345
|
<summary>Returns</summary>
|
|
337
346
|
|
|
338
|
-
Type: `Promise<
|
|
347
|
+
Type: `Promise<Cph.Stream.Symmetric.DecryptReturnType>`
|
|
339
348
|
|
|
340
|
-
- A new Promise that resolves when
|
|
349
|
+
- A new Promise that resolves when Key IV extraction completes returning an object containing:
|
|
350
|
+
- a new instance of `crypto.Decipher` allowing you to add listeners to the `decipher` decryption process.
|
|
351
|
+
- the actual `decrypt` callback that must be called and awaited in order to start the decryption process.
|
|
341
352
|
|
|
342
353
|
</details>
|
|
343
354
|
|
|
@@ -372,9 +383,11 @@ Encrypts a stream using hybrid encryption (symmetric + RSA).
|
|
|
372
383
|
|
|
373
384
|
<summary>Returns</summary>
|
|
374
385
|
|
|
375
|
-
Type: `
|
|
386
|
+
Type: `Cph.Stream.Hybrid.EncryptReturnType`
|
|
376
387
|
|
|
377
|
-
-
|
|
388
|
+
- An object containing:
|
|
389
|
+
- a new instance of `cipher` allowing you to add listeners to the `cipher` encryption process.
|
|
390
|
+
- the actual `encrypt` callback that must be called and awaited to start the encryption process.
|
|
378
391
|
|
|
379
392
|
</details>
|
|
380
393
|
|
|
@@ -408,9 +421,11 @@ Decrypts a stream using hybrid decryption (symmetric + RSA).
|
|
|
408
421
|
|
|
409
422
|
<summary>Returns</summary>
|
|
410
423
|
|
|
411
|
-
Type: `Promise<
|
|
424
|
+
Type: `Promise<Cph.Stream.Hybrid.DecryptReturnType>`
|
|
412
425
|
|
|
413
|
-
- A new Promise that resolves when
|
|
426
|
+
- A new Promise that resolves when Key IV extraction completes returning an object containing:
|
|
427
|
+
- a new instance of `crypto.Decipher` allowing you to add listeners to the `decipher` decryption process.
|
|
428
|
+
- the actual `decrypt` callback that must be called and awaited in order to start the decryption process.
|
|
414
429
|
|
|
415
430
|
</details>
|
|
416
431
|
|
|
@@ -496,6 +511,23 @@ Stream symmetric encryption options.
|
|
|
496
511
|
|
|
497
512
|
---
|
|
498
513
|
|
|
514
|
+
##### `Cph.Stream.Symmetric.EncryptReturnType`
|
|
515
|
+
|
|
516
|
+
Returnign object from `Cipher.streamEncrypt()` method.
|
|
517
|
+
|
|
518
|
+
<details>
|
|
519
|
+
|
|
520
|
+
<summary>Properties</summary>
|
|
521
|
+
|
|
522
|
+
| Property | Type | Description |
|
|
523
|
+
|----------|----------|-------------|
|
|
524
|
+
| `cipher` | `crypto.Cipher` | The `crypto.Cipher` instance. |
|
|
525
|
+
| `encrypt` | `() => Promise<void>` | The actual `encrypt` callback that must be called and awaited in order to start the encryption process. |
|
|
526
|
+
|
|
527
|
+
</details>
|
|
528
|
+
|
|
529
|
+
---
|
|
530
|
+
|
|
499
531
|
##### `Cph.Stream.Symmetric.DecryptOptions`
|
|
500
532
|
|
|
501
533
|
Stream symmetric decryption options.
|
|
@@ -515,6 +547,23 @@ Stream symmetric decryption options.
|
|
|
515
547
|
|
|
516
548
|
---
|
|
517
549
|
|
|
550
|
+
##### `Cph.Stream.Symmetric.DecryptReturnType`
|
|
551
|
+
|
|
552
|
+
Returnign object from awaited `Cipher.streamDecrypt()` method.
|
|
553
|
+
|
|
554
|
+
<details>
|
|
555
|
+
|
|
556
|
+
<summary>Properties</summary>
|
|
557
|
+
|
|
558
|
+
| Property | Type | Description |
|
|
559
|
+
|----------|----------|-------------|
|
|
560
|
+
| `decipher` | `crypto.Decipher` | The `crypto.Decipher` instance. |
|
|
561
|
+
| `decrypt` | `() => Promise<void>` | The actual `decrypt` callback that must be called and awaited in order to start the decryption process. |
|
|
562
|
+
|
|
563
|
+
</details>
|
|
564
|
+
|
|
565
|
+
---
|
|
566
|
+
|
|
518
567
|
##### `Cph.Stream.Hybrid.EncryptOptions`
|
|
519
568
|
|
|
520
569
|
Stream hybrid encryption options.
|
|
@@ -523,6 +572,14 @@ Stream hybrid encryption options.
|
|
|
523
572
|
|
|
524
573
|
---
|
|
525
574
|
|
|
575
|
+
##### `Cph.Stream.Hybrid.EncryptReturnType`
|
|
576
|
+
|
|
577
|
+
Returnign object from `Cipher.hybridEncrypt()` method.
|
|
578
|
+
|
|
579
|
+
- Alias for [`Cph.Stream.Symmetric.EncryptReturnType`](#cphstreamsymmetricencryptreturntype)
|
|
580
|
+
|
|
581
|
+
---
|
|
582
|
+
|
|
526
583
|
##### `Cph.Stream.Hybrid.DecryptOptions`
|
|
527
584
|
|
|
528
585
|
Stream hybrid decryption options.
|
|
@@ -541,6 +598,14 @@ Stream hybrid decryption options.
|
|
|
541
598
|
|
|
542
599
|
---
|
|
543
600
|
|
|
601
|
+
##### `Cph.Stream.Hybrid.DecryptReturnType`
|
|
602
|
+
|
|
603
|
+
Returnign object from awaited `Cipher.hybridDecrypt()` method.
|
|
604
|
+
|
|
605
|
+
- Alias for [`Cph.Stream.Symmetric.DecryptReturnType`](#cphstreamsymmetricdecryptreturntype)
|
|
606
|
+
|
|
607
|
+
---
|
|
608
|
+
|
|
544
609
|
### Examples
|
|
545
610
|
|
|
546
611
|
#### Importing the library
|
|
@@ -609,6 +674,7 @@ const routeHandler = () => {
|
|
|
609
674
|
} )
|
|
610
675
|
|
|
611
676
|
Cipher.streamEncrypt( password, { input, output } )
|
|
677
|
+
.encrypt()
|
|
612
678
|
|
|
613
679
|
return (
|
|
614
680
|
// encrypted stream
|
|
@@ -664,7 +730,9 @@ const routeHandler = () => (
|
|
|
664
730
|
},
|
|
665
731
|
} )
|
|
666
732
|
|
|
667
|
-
Cipher.streamDecrypt( password, { input, output } )
|
|
733
|
+
const { decrypt } = await Cipher.streamDecrypt( password, { input, output } )
|
|
734
|
+
|
|
735
|
+
decrypt()
|
|
668
736
|
|
|
669
737
|
return (
|
|
670
738
|
// decrypted stream
|
|
@@ -729,12 +797,13 @@ const output = new Writable( {
|
|
|
729
797
|
}
|
|
730
798
|
} )
|
|
731
799
|
|
|
732
|
-
|
|
800
|
+
const { encrypt } = Cipher.hybridEncrypt( password, {
|
|
733
801
|
key : keyPair.publicKey,
|
|
734
802
|
padding : crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
|
735
803
|
oaepHash : 'SHA-256',
|
|
736
804
|
}, { input, output } )
|
|
737
805
|
|
|
806
|
+
await encrypt()
|
|
738
807
|
```
|
|
739
808
|
|
|
740
809
|
---
|
|
@@ -762,7 +831,7 @@ const output = new Writable( {
|
|
|
762
831
|
},
|
|
763
832
|
} )
|
|
764
833
|
|
|
765
|
-
await Cipher.hybridDecrypt(
|
|
834
|
+
const { decrypt } = await Cipher.hybridDecrypt(
|
|
766
835
|
{
|
|
767
836
|
key : keyPair.privateKey,
|
|
768
837
|
passphrase: password, // optional passhrase (required if set while generating keypair).
|
|
@@ -771,6 +840,8 @@ await Cipher.hybridDecrypt(
|
|
|
771
840
|
}, { input, output, rsaKeyLength }
|
|
772
841
|
)
|
|
773
842
|
|
|
843
|
+
await decrypt()
|
|
844
|
+
|
|
774
845
|
console.log( Buffer.concat( chunks ).toString() ) // Outputs: 'my top-secret data'
|
|
775
846
|
```
|
|
776
847
|
|
|
@@ -793,6 +864,7 @@ const input = fs.createReadStream( 'my-very-large-top-secret-file.pdf' )
|
|
|
793
864
|
const output = fs.createWriteStream( 'my-very-large-top-secret-file.encrypted' )
|
|
794
865
|
// encrypt
|
|
795
866
|
await Cipher.streamEncrypt( password, { input, output } )
|
|
867
|
+
.encrypt()
|
|
796
868
|
```
|
|
797
869
|
|
|
798
870
|
---
|
|
@@ -809,7 +881,8 @@ const input = fs.createReadStream( 'my-very-large-top-secret-file.encrypted' )
|
|
|
809
881
|
// output where decrypted data is written
|
|
810
882
|
const output = fs.createWriteStream( 'my-very-large-top-secret-file-decrypted.pdf' )
|
|
811
883
|
// decrypt
|
|
812
|
-
await Cipher.streamDecrypt( password, { input, output } )
|
|
884
|
+
const { decrypt } = await Cipher.streamDecrypt( password, { input, output } )
|
|
885
|
+
await decrypt()
|
|
813
886
|
```
|
|
814
887
|
|
|
815
888
|
---
|
|
@@ -852,11 +925,12 @@ const input = fs.createReadStream( 'my-very-large-top-secret-file.pdf' )
|
|
|
852
925
|
// output where encrypted data is written
|
|
853
926
|
const output = fs.createWriteStream( 'my-very-large-top-secret-file.encrypted' )
|
|
854
927
|
// encrypt
|
|
855
|
-
|
|
928
|
+
const { encrypt } = Cipher.hybridEncrypt( password, {
|
|
856
929
|
key : keyPair.publicKey,
|
|
857
930
|
padding : crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
|
858
931
|
oaepHash : 'SHA-256',
|
|
859
932
|
}, { input, output } )
|
|
933
|
+
await encrypt()
|
|
860
934
|
```
|
|
861
935
|
|
|
862
936
|
---
|
|
@@ -873,7 +947,7 @@ const input = fs.createReadStream( 'my-very-large-top-secret-file.encrypted' )
|
|
|
873
947
|
// output where decrypted data is written
|
|
874
948
|
const output = fs.createWriteStream( 'my-very-large-top-secret-file-decrypted.pdf' )
|
|
875
949
|
// decrypt
|
|
876
|
-
await Cipher.hybridDecrypt(
|
|
950
|
+
const { decrypt } = await Cipher.hybridDecrypt(
|
|
877
951
|
{
|
|
878
952
|
key : keyPair.privateKey,
|
|
879
953
|
passphrase: password, // optional passhrase (required if set while generating keypair).
|
|
@@ -927,16 +1001,7 @@ pnpm test:watch
|
|
|
927
1001
|
pnpm test:ci
|
|
928
1002
|
```
|
|
929
1003
|
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
```bash
|
|
933
|
-
pnpm test:buffer-in-memory
|
|
934
|
-
pnpm test:file-symmetric
|
|
935
|
-
pnpm test:file-hybrid
|
|
936
|
-
pnpm test:stream-symmetric
|
|
937
|
-
pnpm test:stream-hybrid
|
|
938
|
-
pnpm test:misc
|
|
939
|
-
```
|
|
1004
|
+
- See [`package.json`](./package.json) file scripts for more info.
|
|
940
1005
|
|
|
941
1006
|
Run tests with coverage.
|
|
942
1007
|
|
|
@@ -952,9 +1017,14 @@ test:coverage:serve
|
|
|
952
1017
|
|
|
953
1018
|
### Contributing
|
|
954
1019
|
|
|
955
|
-
Contributions are truly welcome
|
|
1020
|
+
Contributions are truly welcome!
|
|
1021
|
+
|
|
956
1022
|
Please refer to the [Contributing Doc](./CONTRIBUTING.md) for more information on how to start contributing to this project.
|
|
957
1023
|
|
|
1024
|
+
Help keep this project up to date with [GitHub Sponsor][sponsor-url].
|
|
1025
|
+
|
|
1026
|
+
[![GitHub Sponsor][sponsor-badge]][sponsor-url]
|
|
1027
|
+
|
|
958
1028
|
---
|
|
959
1029
|
|
|
960
1030
|
### Security
|
|
@@ -964,30 +1034,30 @@ If you believe you have found a security vulnerability, we encourage you to **_r
|
|
|
964
1034
|
### Made with ☕
|
|
965
1035
|
|
|
966
1036
|
<table style='display:flex;gap:20px;'>
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
1037
|
+
<tbody>
|
|
1038
|
+
<tr>
|
|
1039
|
+
<td>
|
|
1040
|
+
<img alt="avatar" src='https://avatars.githubusercontent.com/u/35973186' style='width:60px;border-radius:50%;object-fit:contain;'>
|
|
1041
|
+
</td>
|
|
1042
|
+
<td>
|
|
1043
|
+
<table style='display:flex;gap:2px;flex-direction:column;'>
|
|
1044
|
+
<tbody>
|
|
1045
|
+
<tr>
|
|
1046
|
+
<td>
|
|
1047
|
+
<a href='https://github.com/alessiofrittoli' target='_blank' rel='noopener'>Alessio Frittoli</a>
|
|
1048
|
+
</td>
|
|
1049
|
+
</tr>
|
|
1050
|
+
<tr>
|
|
1051
|
+
<td>
|
|
1052
|
+
<small>
|
|
1053
|
+
<a href='https://alessiofrittoli.it' target='_blank' rel='noopener'>https://alessiofrittoli.it</a> |
|
|
1054
|
+
<a href='mailto:info@alessiofrittoli.it' target='_blank' rel='noopener'>info@alessiofrittoli.it</a>
|
|
1055
|
+
</small>
|
|
1056
|
+
</td>
|
|
1057
|
+
</tr>
|
|
1058
|
+
</tbody>
|
|
1059
|
+
</table>
|
|
1060
|
+
</td>
|
|
1061
|
+
</tr>
|
|
1062
|
+
</tbody>
|
|
993
1063
|
</table>
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
2
|
import { CoerceToUint8ArrayInput } from '@alessiofrittoli/crypto-buffer/coercion';
|
|
3
3
|
import { Cph } from './types.mjs';
|
|
4
|
-
import '@alessiofrittoli/crypto-buffer';
|
|
5
4
|
import 'stream';
|
|
5
|
+
import '@alessiofrittoli/crypto-buffer';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Utility class for AES encryption and decryption following [NIST SP 800-38D](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf) standard reccomendations.
|
|
@@ -80,9 +80,11 @@ declare class Cipher {
|
|
|
80
80
|
*
|
|
81
81
|
* @param secret The secret key used to encrypt the `data`.
|
|
82
82
|
* @param options Additional options.
|
|
83
|
-
* @returns
|
|
83
|
+
* @returns An object containing:
|
|
84
|
+
* - a new instance of `crypto.Cipher` allowing you to add listeners to the `cipher` encryption process.
|
|
85
|
+
* - the actual `encrypt` callback that must be called and awaited in order to start the encryption process.
|
|
84
86
|
*/
|
|
85
|
-
static streamEncrypt(secret: CoerceToUint8ArrayInput, options: Cph.Stream.Symmetric.EncryptOptions):
|
|
87
|
+
static streamEncrypt(secret: CoerceToUint8ArrayInput, options: Cph.Stream.Symmetric.EncryptOptions): Cph.Stream.Symmetric.EncryptReturnType;
|
|
86
88
|
/**
|
|
87
89
|
* Decrypt a `Readable` to a `Writable` Stream.
|
|
88
90
|
*
|
|
@@ -90,9 +92,11 @@ declare class Cipher {
|
|
|
90
92
|
*
|
|
91
93
|
* @param secret The secret key used to encrypt the `data`.
|
|
92
94
|
* @param options Additional options.
|
|
93
|
-
* @returns A new Promise that resolves
|
|
95
|
+
* @returns A new Promise that resolves when Key IV extraction completes returning an object containing:
|
|
96
|
+
* - a new instance of `crypto.Decipher` allowing you to add listeners to the `decipher` decryption process.
|
|
97
|
+
* - the actual `decrypt` callback that must be called and awaited in order to start the decryption process.
|
|
94
98
|
*/
|
|
95
|
-
static streamDecrypt(secret: CoerceToUint8ArrayInput, options: Cph.Stream.Symmetric.DecryptOptions): Promise<
|
|
99
|
+
static streamDecrypt(secret: CoerceToUint8ArrayInput, options: Cph.Stream.Symmetric.DecryptOptions): Promise<Cph.Stream.Symmetric.DecryptReturnType>;
|
|
96
100
|
/**
|
|
97
101
|
* Encrypt a `Readable` to a `Writable` Stream with hybird Encryption.
|
|
98
102
|
*
|
|
@@ -101,9 +105,11 @@ declare class Cipher {
|
|
|
101
105
|
* @param secret The secret key used to encrypt the stream.
|
|
102
106
|
* @param publicKey The RSA public key used to encrypt the symmetric key.
|
|
103
107
|
* @param options Options for the stream encryption.
|
|
104
|
-
* @returns
|
|
108
|
+
* @returns An object containing:
|
|
109
|
+
* - a new instance of `crypto.Cipher` allowing you to add listeners to the `cipher` encryption process.
|
|
110
|
+
* - the actual `encrypt` callback that must be called and awaited in order to start the encryption process.
|
|
105
111
|
*/
|
|
106
|
-
static hybridEncrypt(secret: CoerceToUint8ArrayInput, publicKey: crypto.RsaPublicKey | crypto.RsaPrivateKey | crypto.KeyLike, options: Cph.Stream.Hybrid.EncryptOptions):
|
|
112
|
+
static hybridEncrypt(secret: CoerceToUint8ArrayInput, publicKey: crypto.RsaPublicKey | crypto.RsaPrivateKey | crypto.KeyLike, options: Cph.Stream.Hybrid.EncryptOptions): Cph.Stream.Hybrid.EncryptReturnType;
|
|
107
113
|
/**
|
|
108
114
|
* Decrypt a `Readable` to a `Writable` Stream with hybrid Decryption.
|
|
109
115
|
*
|
|
@@ -111,9 +117,11 @@ declare class Cipher {
|
|
|
111
117
|
*
|
|
112
118
|
* @param privateKey The RSA private key used to decrypt the symmetric key.
|
|
113
119
|
* @param options Options for the stream decryption.
|
|
114
|
-
* @returns
|
|
120
|
+
* @returns A new Promise that resolves when Key IV extraction completes returning an object containing:
|
|
121
|
+
* - a new instance of `crypto.Decipher` allowing you to add listeners to the `decipher` decryption process.
|
|
122
|
+
* - the actual `decrypt` callback that must be called and awaited in order to start the decryption process.
|
|
115
123
|
*/
|
|
116
|
-
static hybridDecrypt(privateKey: crypto.RsaPrivateKey | crypto.KeyLike, options: Cph.Stream.Hybrid.DecryptOptions): Promise<
|
|
124
|
+
static hybridDecrypt(privateKey: crypto.RsaPrivateKey | crypto.KeyLike, options: Cph.Stream.Hybrid.DecryptOptions): Promise<Cph.Stream.Hybrid.DecryptReturnType>;
|
|
117
125
|
/**
|
|
118
126
|
* Handle pipe flow to encrypt a Stream.
|
|
119
127
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
2
|
import { CoerceToUint8ArrayInput } from '@alessiofrittoli/crypto-buffer/coercion';
|
|
3
3
|
import { Cph } from './types.js';
|
|
4
|
-
import '@alessiofrittoli/crypto-buffer';
|
|
5
4
|
import 'stream';
|
|
5
|
+
import '@alessiofrittoli/crypto-buffer';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Utility class for AES encryption and decryption following [NIST SP 800-38D](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf) standard reccomendations.
|
|
@@ -80,9 +80,11 @@ declare class Cipher {
|
|
|
80
80
|
*
|
|
81
81
|
* @param secret The secret key used to encrypt the `data`.
|
|
82
82
|
* @param options Additional options.
|
|
83
|
-
* @returns
|
|
83
|
+
* @returns An object containing:
|
|
84
|
+
* - a new instance of `crypto.Cipher` allowing you to add listeners to the `cipher` encryption process.
|
|
85
|
+
* - the actual `encrypt` callback that must be called and awaited in order to start the encryption process.
|
|
84
86
|
*/
|
|
85
|
-
static streamEncrypt(secret: CoerceToUint8ArrayInput, options: Cph.Stream.Symmetric.EncryptOptions):
|
|
87
|
+
static streamEncrypt(secret: CoerceToUint8ArrayInput, options: Cph.Stream.Symmetric.EncryptOptions): Cph.Stream.Symmetric.EncryptReturnType;
|
|
86
88
|
/**
|
|
87
89
|
* Decrypt a `Readable` to a `Writable` Stream.
|
|
88
90
|
*
|
|
@@ -90,9 +92,11 @@ declare class Cipher {
|
|
|
90
92
|
*
|
|
91
93
|
* @param secret The secret key used to encrypt the `data`.
|
|
92
94
|
* @param options Additional options.
|
|
93
|
-
* @returns A new Promise that resolves
|
|
95
|
+
* @returns A new Promise that resolves when Key IV extraction completes returning an object containing:
|
|
96
|
+
* - a new instance of `crypto.Decipher` allowing you to add listeners to the `decipher` decryption process.
|
|
97
|
+
* - the actual `decrypt` callback that must be called and awaited in order to start the decryption process.
|
|
94
98
|
*/
|
|
95
|
-
static streamDecrypt(secret: CoerceToUint8ArrayInput, options: Cph.Stream.Symmetric.DecryptOptions): Promise<
|
|
99
|
+
static streamDecrypt(secret: CoerceToUint8ArrayInput, options: Cph.Stream.Symmetric.DecryptOptions): Promise<Cph.Stream.Symmetric.DecryptReturnType>;
|
|
96
100
|
/**
|
|
97
101
|
* Encrypt a `Readable` to a `Writable` Stream with hybird Encryption.
|
|
98
102
|
*
|
|
@@ -101,9 +105,11 @@ declare class Cipher {
|
|
|
101
105
|
* @param secret The secret key used to encrypt the stream.
|
|
102
106
|
* @param publicKey The RSA public key used to encrypt the symmetric key.
|
|
103
107
|
* @param options Options for the stream encryption.
|
|
104
|
-
* @returns
|
|
108
|
+
* @returns An object containing:
|
|
109
|
+
* - a new instance of `crypto.Cipher` allowing you to add listeners to the `cipher` encryption process.
|
|
110
|
+
* - the actual `encrypt` callback that must be called and awaited in order to start the encryption process.
|
|
105
111
|
*/
|
|
106
|
-
static hybridEncrypt(secret: CoerceToUint8ArrayInput, publicKey: crypto.RsaPublicKey | crypto.RsaPrivateKey | crypto.KeyLike, options: Cph.Stream.Hybrid.EncryptOptions):
|
|
112
|
+
static hybridEncrypt(secret: CoerceToUint8ArrayInput, publicKey: crypto.RsaPublicKey | crypto.RsaPrivateKey | crypto.KeyLike, options: Cph.Stream.Hybrid.EncryptOptions): Cph.Stream.Hybrid.EncryptReturnType;
|
|
107
113
|
/**
|
|
108
114
|
* Decrypt a `Readable` to a `Writable` Stream with hybrid Decryption.
|
|
109
115
|
*
|
|
@@ -111,9 +117,11 @@ declare class Cipher {
|
|
|
111
117
|
*
|
|
112
118
|
* @param privateKey The RSA private key used to decrypt the symmetric key.
|
|
113
119
|
* @param options Options for the stream decryption.
|
|
114
|
-
* @returns
|
|
120
|
+
* @returns A new Promise that resolves when Key IV extraction completes returning an object containing:
|
|
121
|
+
* - a new instance of `crypto.Decipher` allowing you to add listeners to the `decipher` decryption process.
|
|
122
|
+
* - the actual `decrypt` callback that must be called and awaited in order to start the decryption process.
|
|
115
123
|
*/
|
|
116
|
-
static hybridDecrypt(privateKey: crypto.RsaPrivateKey | crypto.KeyLike, options: Cph.Stream.Hybrid.DecryptOptions): Promise<
|
|
124
|
+
static hybridDecrypt(privateKey: crypto.RsaPrivateKey | crypto.KeyLike, options: Cph.Stream.Hybrid.DecryptOptions): Promise<Cph.Stream.Hybrid.DecryptReturnType>;
|
|
117
125
|
/**
|
|
118
126
|
* Handle pipe flow to encrypt a Stream.
|
|
119
127
|
*
|
package/dist/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var m=require('crypto'),stream=require('stream'),coercion=require('@alessiofrittoli/crypto-buffer/coercion');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var m__default=/*#__PURE__*/_interopDefault(m);var t=class t{static encrypt(r,e,o={}){let a=coercion.coerceToUint8Array(r),{salt:c,Key:s,IV:n,AAD:p,options:{algorithm:i,authTag:h}}=t.newKeyIV(e,o);if(t.isCBC(i)){let T=m__default.default.createCipheriv(i,s,n),d=Buffer.concat([T.update(a),T.final()]);return Buffer.concat([c,n,d])}let y=m__default.default.createCipheriv(i,s,n,{authTagLength:h});t.isCCM(i)&&y.setAAD(p,{plaintextLength:a.length}),(t.isGCM(i)||t.isOCB(i))&&y.setAAD(p);let u=Buffer.concat([y.update(a),y.final()]),l=y.getAuthTag();return Buffer.concat([c,n,p,l,u])}static decrypt(r,e,o={}){let a=coercion.coerceToUint8Array(r),c=coercion.coerceToUint8Array(e),s=t.resolveOptions(o),{algorithm:n}=s,p=a.subarray(0,s.salt);a=a.subarray(s.salt);let i=a.subarray(0,s.iv);a=a.subarray(s.iv);let h=m__default.default.scryptSync(c,p,s.length);if(t.isCBC(n)){let f=m__default.default.createDecipheriv(s.algorithm,h,i);return Buffer.concat([f.update(a),f.final()])}let y=s.aadLength,u=s.authTag,l=a.subarray(0,y);a=a.subarray(y);let T=a.subarray(0,u);a=a.subarray(u);let d=m__default.default.createDecipheriv(n,h,i,{authTagLength:u});return t.isCCM(n)&&d.setAAD(l,{plaintextLength:a.length}),(t.isGCM(n)||t.isOCB(n))&&d.setAAD(l),d.setAuthTag(T),Buffer.concat([d.update(a),d.final()])}static streamEncrypt(r,e){e.algorithm||(e.algorithm=t.DEFAULT_ALGORITHM.stream);let{Key:o,IV:a,options:{input:c,output:s,algorithm:n,salt:p,iv:i,authTag:h}}=t.newKeyIV(r,e),y=t.encrypt(Buffer.concat([o,a]),r,{algorithm:n,salt:p,iv:i,authTag:h}),u=m__default.default.createCipheriv(n,o,a);return {cipher:u,encrypt:()=>t.stream({cipher:u,input:c,output:s,encryptedKey:y})}}static streamDecrypt(r,e){e.algorithm||(e.algorithm=t.DEFAULT_ALGORITHM.stream);let{input:o,output:a,algorithm:c,salt:s,iv:n,authTag:p,length:i}=t.resolveOptions(e),h=i+n+s+n+p;return t.extractKeyIV(o,h).then(([y,u])=>{if(u.errored)throw u.errored;let l=t.decrypt(y,r,{algorithm:c,salt:s,iv:n,authTag:p}),T=l.subarray(0,i),d=l.subarray(i),f=m__default.default.createDecipheriv(c,T,d);return {decipher:f,decrypt:()=>t.decipherStream({decipher:f,input:u,output:a})}})}static hybridEncrypt(r,e,o){o.algorithm||(o.algorithm=t.DEFAULT_ALGORITHM.stream);let{Key:a,IV:c,options:{algorithm:s,input:n,output:p}}=t.newKeyIV(r,o),i=m__default.default.publicEncrypt(e,Buffer.concat([a,c])),h=m__default.default.createCipheriv(s,a,c);return {cipher:h,encrypt:()=>t.stream({cipher:h,input:n,output:p,encryptedKey:i})}}static hybridDecrypt(r,e){e.algorithm||(e.algorithm=t.DEFAULT_ALGORITHM.stream);let{input:o,output:a,algorithm:c,length:s,rsaKeyLength:n}=t.resolveOptions(e);return t.extractKeyIV(o,n).then(([p,i])=>{let h=m__default.default.privateDecrypt(r,p),y=h.subarray(0,s),u=h.subarray(s),l=m__default.default.createDecipheriv(c,y,u);return {decipher:l,decrypt:()=>t.decipherStream({decipher:l,input:i,output:a})}})}static stream(r){let{cipher:e,encryptedKey:o,input:a,output:c}=r;return new Promise((s,n)=>{e.on("error",n),a.on("error",n),c.on("error",n),c.on("finish",s),c.write(o),a.pipe(e).pipe(c);})}static decipherStream(r){let{decipher:e,input:o,output:a}=r;return new Promise((c,s)=>{e.on("error",s),o.on("error",s),a.on("error",s),a.on("finish",c),o.pipe(e).pipe(a);})}static extractKeyIV(r,e){return new Promise((o,a)=>{let c=Buffer.alloc(0),s=0,n=false,p=new stream.Transform({async transform(i,h,y){if(c.length<e&&(c=Buffer.concat([c,i])),s+=i.length,c.length>e){let u=Math.max(0,c.length-e);c=c.subarray(0,e);let l=i.subarray(u*-1);return n||(o([c,this]),n=true),this.push(l,h),y()}return s>e&&(n||(o([c,this]),n=true),this.push(i,h)),y()},final(i){return c.length<e?i(new Error("The extracted KeyIV length is less than the expected length.")):i()}});p.on("error",a),r.on("error",i=>{p.destroy(i),a(i);}),r.pipe(p);})}static newKeyIV(r,e={}){let o=coercion.coerceToUint8Array(r),a=t.resolveOptions(e),c=m__default.default.randomBytes(a.salt),s=m__default.default.scryptSync(o,c,a.length),n=m__default.default.randomBytes(a.iv),p=a.aad||m__default.default.scryptSync(s,c,a.aadLength);return {options:a,Key:s,IV:n,AAD:p,salt:c}}static resolveOptions(r={}){let e={...r};e.aad&&(e.aad=coercion.coerceToUint8Array(e.aad)),e.salt||(e.salt=t.SALT_LENGTH.default),e.authTag||(e.authTag=t.AUTH_TAG_LENGTH.default),e.aadLength=e.aad?.length||e.aadLength||t.AAD_LENGTH.default,e.salt=Math.min(Math.max(e.salt,t.SALT_LENGTH.min),t.SALT_LENGTH.max),e.authTag=Math.min(Math.max(e.authTag,t.AUTH_TAG_LENGTH.min),t.AUTH_TAG_LENGTH.max),e.aad||(e.aadLength=Math.min(Math.max(e.aadLength,t.AAD_LENGTH.min),t.AAD_LENGTH.max));let{keyLength:o,algorithm:a}=t.getKeyLength(r.algorithm);return e.algorithm=a,e.length=o,e.iv=t.getIVLength(a,r),e}static getIVLength(r=t.DEFAULT_ALGORITHM.buffer,e={}){switch(r){case "aes-128-ccm":case "aes-128-ocb":case "aes-192-ccm":case "aes-192-ocb":case "aes-256-ccm":case "aes-256-ocb":return 8;case "chacha20-poly1305":return 12;default:return Math.min(Math.max(e.iv||t.IV_LENGTH.default,t.IV_LENGTH.min),t.IV_LENGTH.max)}}static getKeyLength(r=t.DEFAULT_ALGORITHM.buffer){switch(r){case "chacha20-poly1305":return {algorithm:r,keyLength:256/8};case "aes-128-cbc":case "aes-128-ccm":case "aes-128-gcm":case "aes-128-ocb":return {algorithm:r,keyLength:128/8};case "aes-192-cbc":case "aes-192-ccm":case "aes-192-gcm":case "aes-192-ocb":return {algorithm:r,keyLength:192/8};case "aes-256-cbc":case "aes-256-ccm":case "aes-256-gcm":case "aes-256-ocb":default:return {algorithm:r,keyLength:256/8}}}static isGCM(r){return r==="aes-128-gcm"||r==="aes-192-gcm"||r==="aes-256-gcm"}static isCCM(r){return r==="aes-128-ccm"||r==="aes-192-ccm"||r==="aes-256-ccm"||r==="chacha20-poly1305"}static isOCB(r){return r==="aes-128-ocb"||r==="aes-192-ocb"||r==="aes-256-ocb"}static isCBC(r){return r==="aes-128-cbc"||r==="aes-192-cbc"||r==="aes-256-cbc"}};t.SALT_LENGTH={min:16,max:64,default:32},t.IV_LENGTH={min:8,max:32,default:16},t.AUTH_TAG_LENGTH={min:4,max:16,default:16},t.AAD_LENGTH={min:16,max:128,default:32},t.DEFAULT_ALGORITHM={buffer:"aes-256-gcm",stream:"aes-256-cbc"},t.ALGORITHMS=["aes-128-cbc","aes-128-ccm","aes-128-gcm","aes-128-ocb","aes-192-cbc","aes-192-ccm","aes-192-gcm","aes-192-ocb","aes-256-cbc","aes-256-ccm","aes-256-gcm","aes-256-ocb","chacha20-poly1305"];var A=t;exports.Cipher=A;//# sourceMappingURL=index.js.map
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["_Cipher","data","secret","options","_data","coerceToUint8Array","salt","Key","IV","AAD","algorithm","authTagLength","cipher","crypto","encrypted","authTag","_secret","_options","decipher","AADLength","input","output","iv","encryptedKey","length","keyIvLength","encryptedKeyIV","KeyIV","publicKey","privateKey","rsaKeyLength","resolve","reject","keyLength","bytesRead","resolved","transform","Transform","chunk","encoding","callback","bytesLoss","subchunk","error","Cipher"],"mappings":"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","file":"index.js","sourcesContent":["import crypto from 'crypto'\nimport { Transform } from 'stream'\nimport type { Readable, Writable } from 'stream'\nimport { coerceToUint8Array, type CoerceToUint8ArrayInput } from '@alessiofrittoli/crypto-buffer/coercion'\n\nimport type { Cph } from './types'\n\n\n\n/**\n * INTERNAL USE ONLY\n */\ninterface StreamEncryptOptions\n{\n\tcipher\t\t: crypto.Cipher\n\tencryptedKey: Buffer\n\tinput\t\t: Readable\n\toutput\t\t: Writable\n}\n\n\n/**\n * INTERNAL USE ONLY\n */\ninterface StreamDecryptOptions\n{\n\tdecipher\t: crypto.Decipher\n\tinput\t\t: Readable\n\toutput\t\t: Writable\n}\n\n\n/**\n * Utility class for AES encryption and decryption following [NIST SP 800-38D](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf) standard reccomendations.\n */\nexport class Cipher\n{\n\t/**\n\t * Cipher default `salt` lengths.\n\t */\n\tstatic readonly SALT_LENGTH = {\n\t\tmin\t\t: 16,\n\t\tmax\t\t: 64,\n\t\tdefault\t: 32,\n\t} as const\n\n\n\t/**\n\t * Cipher default `IV` lengths.\n\t */\n\tstatic readonly IV_LENGTH = {\n\t\tmin\t\t: 8,\n\t\tmax\t\t: 32,\n\t\tdefault\t: 16,\n\t} as const\n\n\n\t/**\n\t * Cipher default `Auth Tag` lengths.\n\t */\n\tstatic readonly AUTH_TAG_LENGTH = {\n\t\tmin\t\t: 4,\n\t\tmax\t\t: 16,\n\t\tdefault\t: 16,\n\t} as const\n\t\n\t\n\t/**\n\t * Cipher default `Additional Authenticated Data` lengths.\n\t */\n\tstatic readonly AAD_LENGTH = {\n\t\tmin\t\t: 16,\n\t\tmax\t\t: 128,\n\t\tdefault\t: 32,\n\t} as const\n\t\n\n\t/**\n\t * Default AES algorithms used based on functionality.\n\t */\n\tstatic readonly DEFAULT_ALGORITHM = {\n\t\tbuffer: 'aes-256-gcm',\n\t\tstream: 'aes-256-cbc',\n\t} as const\n\n\n\t/**\n\t * Supported AES algorithms.\n\t */\n\tstatic readonly ALGORITHMS: Cph.AesAlgorithm[] = [\n\t\t'aes-128-cbc', 'aes-128-ccm', 'aes-128-gcm', 'aes-128-ocb',\n\t\t'aes-192-cbc', 'aes-192-ccm', 'aes-192-gcm', 'aes-192-ocb',\n\t\t'aes-256-cbc', 'aes-256-ccm', 'aes-256-gcm', 'aes-256-ocb',\n\t\t'chacha20-poly1305'\n\t] as const\n\n\n\t/**\n\t * Encrypt in-memory data buffer.\n\t *\n\t * ⚠️ This is not suitable for large data. Use {@link Cipher.streamEncrypt()} or {@link Cipher.hybridEncrypt()} methods for large data encryption.\n\t *\n\t * @param\tdata\tThe data to encrypt.\n\t * @param\tsecret\tThe secret key used to encrypt the `data`.\n\t * @param\toptions\t( Optional ) Additional options.\n\t * @returns\tThe encrypted result Buffer.\n\t */\n\tstatic encrypt(\n\t\tdata\t: CoerceToUint8ArrayInput,\n\t\tsecret\t: CoerceToUint8ArrayInput,\n\t\toptions\t: Cph.Options = {},\n\t): Buffer\n\t{\n\t\tconst _data = coerceToUint8Array( data )\n\n\t\tconst {\n\t\t\tsalt, Key, IV, AAD,\n\t\t\toptions: { algorithm, authTag: authTagLength },\n\t\t} = Cipher.newKeyIV( secret, options )\n\n\t\tif ( Cipher.isCBC( algorithm ) ) {\n\t\t\tconst cipher\t= crypto.createCipheriv( algorithm, Key, IV )\n\t\t\tconst encrypted\t= Buffer.concat( [ cipher.update( _data ), cipher.final() ] )\n\n\t\t\treturn Buffer.concat( [ salt, IV, encrypted ] )\n\t\t}\n\n\n\t\tconst cipher = (\n\t\t\tcrypto.createCipheriv(\n\t\t\t\t// @ts-expect-error `crypto.createCipheriv` cannot infer the correct overload based on the given union type algorithm.\n\t\t\t\talgorithm, Key, IV, { authTagLength }\n\t\t\t)\n\t\t)\n\t\t\n\t\t\n\t\tif ( Cipher.isCCM( algorithm ) ) {\n\t\t\t// AES-CCM requires `plaintextLength`\n\t\t\tcipher.setAAD( AAD, { plaintextLength: _data.length } )\n\t\t}\n\n\t\tif ( Cipher.isGCM( algorithm ) || Cipher.isOCB( algorithm ) ) {\n\t\t\t// AES-GCM and AES-OCB doesn't require `plaintextLength`\n\t\t\tcipher.setAAD( AAD )\n\t\t}\n\n\t\tconst encrypted\t= Buffer.concat( [ cipher.update( _data ), cipher.final() ] )\n\t\tconst authTag\t= cipher.getAuthTag()\n\n\t\treturn Buffer.concat( [ salt, IV, AAD, authTag, encrypted ] )\n\t}\n\n\n\t/**\n\t * Decrypt in-memory data buffer.\n\t *\n\t * ⚠️ This is not suitable for large data. Use {@link Cipher.streamDecrypt()} or {@link Cipher.hybridDecrypt()} methods for large data decryption.\n\t *\n\t * @param\tdata\tThe data to decrypt.\n\t * @param\tsecret\tThe secret key used to decrypt the `data`.\n\t * @param\toptions\t( Optional ) Additional options. Must be the same used while encrypting data.\n\t * @returns\tThe decrypted data Buffer.\n\t */\n\tstatic decrypt(\n\t\tdata\t: CoerceToUint8ArrayInput,\n\t\tsecret\t: CoerceToUint8ArrayInput,\n\t\toptions\t: Cph.Options = {},\n\t): Buffer\n\t{\n\t\tlet _data\t\t\t= coerceToUint8Array( data )\n\t\tconst _secret\t\t= coerceToUint8Array( secret )\n\t\tconst _options\t\t= Cipher.resolveOptions( options )\n\t\tconst { algorithm }\t= _options\n\n\t\tconst salt\t\t= _data.subarray( 0, _options.salt )\n\t\t_data\t\t\t= _data.subarray( _options.salt )\n\t\tconst IV\t\t= _data.subarray( 0, _options.iv )\n\t\t_data\t\t\t= _data.subarray( _options.iv )\n\t\tconst Key\t\t= crypto.scryptSync( _secret, salt, _options.length )\n\n\t\tif ( Cipher.isCBC( algorithm ) ) {\n\t\t\tconst decipher = (\n\t\t\t\tcrypto.createDecipheriv( _options.algorithm, Key, IV )\n\t\t\t)\n\n\t\t\treturn (\n\t\t\t\tBuffer.concat( [ decipher.update( _data ), decipher.final() ] )\n\t\t\t)\n\t\t}\n\n\t\tconst AADLength\t\t= _options.aadLength\n\t\tconst authTagLength\t= _options.authTag\n\t\tconst AAD\t\t\t= _data.subarray( 0, AADLength )\n\t\t_data\t\t\t\t= _data.subarray( AADLength )\n\t\tconst authTag\t\t= _data.subarray( 0, authTagLength )\n\t\t_data\t\t\t\t= _data.subarray( authTagLength )\n\n\n\t\tconst decipher = (\n\t\t\tcrypto.createDecipheriv(\n\t\t\t\t// @ts-expect-error `crypto.createDecipheriv` cannot infer the correct overload based on the given union type algorithm.\n\t\t\t\talgorithm, Key, IV, { authTagLength }\n\t\t\t)\n\t\t)\n\n\t\tif ( Cipher.isCCM( algorithm ) ) {\n\t\t\t// AES-CCM requires `plaintextLength`\n\t\t\tdecipher.setAAD( AAD, { plaintextLength: _data.length } )\n\t\t}\n\n\t\tif ( Cipher.isGCM( algorithm ) || Cipher.isOCB( algorithm ) ) {\n\t\t\t// AES-GCM and AES-OCB doesn't require `plaintextLength`\n\t\t\tdecipher.setAAD( AAD )\n\t\t}\n\n\t\tdecipher.setAuthTag( authTag )\n\t\n\t\treturn (\n\t\t\tBuffer.concat( [ decipher.update( _data ), decipher.final() ] )\n\t\t)\n\n\t}\n\n\n\t/**\n\t * Encrypt a `Readable` to a `Writable` Stream.\n\t * \n\t * The `Readable` Stream could be 'in-memory buffer' or 'file' based.\n\t * \n\t * @param\tsecret\tThe secret key used to encrypt the `data`.\n\t * @param\toptions Additional options.\n\t * @returns An object containing:\n\t * \t- a new instance of `crypto.Cipher` allowing you to add listeners to the `cipher` encryption process.\n\t * \t- the actual `encrypt` callback that must be called and awaited in order to start the encryption process.\n\t */\n\tstatic streamEncrypt(\n\t\tsecret\t: CoerceToUint8ArrayInput,\n\t\toptions\t: Cph.Stream.Symmetric.EncryptOptions,\n\t): Cph.Stream.Symmetric.EncryptReturnType\n\t{\n\t\toptions.algorithm ||= Cipher.DEFAULT_ALGORITHM.stream\n\n\t\tconst {\n\t\t\tKey, IV, options: { input, output, algorithm, salt, iv, authTag },\n\t\t} = Cipher.newKeyIV<Cph.Stream.Symmetric.EncryptResolvedOptions>( secret, options )\n\n\t\tconst encryptedKey = (\n\t\t\tCipher.encrypt( Buffer.concat( [ Key, IV ] ), secret, { algorithm, salt, iv, authTag } )\n\t\t)\n\n\t\tconst cipher = crypto.createCipheriv( algorithm, Key, IV )\n\t\tconst encrypt = () => (\n\t\t\tCipher.stream( {\n\t\t\t\tcipher, input, output, encryptedKey\n\t\t\t} )\n\t\t)\n\n\t\treturn { cipher, encrypt }\n\t}\n\n\n\t/**\n\t * Decrypt a `Readable` to a `Writable` Stream.\n\t * \n\t * The `Readable` Stream could be 'in-memory buffer' or 'file' based.\n\t * \n\t * @param\tsecret\tThe secret key used to encrypt the `data`.\n\t * @param\toptions Additional options.\n\t * @returns A new Promise that resolves when Key IV extraction completes returning an object containing:\n\t * \t- a new instance of `crypto.Decipher` allowing you to add listeners to the `decipher` decryption process.\n\t * \t- the actual `decrypt` callback that must be called and awaited in order to start the decryption process.\n\t */\n\tstatic streamDecrypt(\n\t\tsecret\t: CoerceToUint8ArrayInput,\n\t\toptions\t: Cph.Stream.Symmetric.DecryptOptions,\n\t): Promise<Cph.Stream.Symmetric.DecryptReturnType>\n\t{\n\t\toptions.algorithm ||= Cipher.DEFAULT_ALGORITHM.stream\n\n\t\tconst {\n\t\t\tinput, output, algorithm, salt, iv, authTag, length\n\t\t} = Cipher.resolveOptions<Cph.Stream.Symmetric.DecryptResolvedOptions>( options )\n\n\t\tconst keyIvLength = (\n\t\t\tlength + iv\n\t\t\t+ salt + iv + authTag\n\t\t)\n\n\t\treturn (\n\t\t\tCipher.extractKeyIV( input, keyIvLength )\n\t\t\t\t.then( ( [ encryptedKeyIV, input ] ) => {\n\t\t\t\t\t/**\n\t\t\t\t\t * Check if input has error and re-throw if so.\n\t\t\t\t\t * This is required since `.on( 'error' )` listeners attached in\n\t\t\t\t\t * `Cipher.decipherStream()` get attached too late (error event already emitted).\n\t\t\t\t\t */\n\t\t\t\t\tif ( input.errored ) throw input.errored\n\t\t\t\t\t\n\t\t\t\t\tconst KeyIV = (\n\t\t\t\t\t\tCipher.decrypt( encryptedKeyIV, secret, { algorithm, salt, iv, authTag } )\n\t\t\t\t\t)\n\n\t\t\t\t\tconst Key\t\t= KeyIV.subarray( 0, length )\n\t\t\t\t\tconst IV\t\t= KeyIV.subarray( length )\n\t\t\t\t\tconst decipher\t= crypto.createDecipheriv( algorithm, Key, IV )\n\t\n\t\t\t\t\tconst decrypt = () => (\n\t\t\t\t\t\tCipher.decipherStream(\n\t\t\t\t\t\t\t{ decipher, input, output }\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\n\t\t\t\t\treturn { decipher, decrypt }\n\t\t\t\t} )\n\t\t)\n\t}\n\n\n\t/**\n\t * Encrypt a `Readable` to a `Writable` Stream with hybird Encryption.\n\t *\n\t * The `Readable` Stream could be 'in-memory buffer' or 'file' based.\n\t *\n\t * @param\tsecret\t\tThe secret key used to encrypt the stream.\n\t * @param\tpublicKey\tThe RSA public key used to encrypt the symmetric key.\n\t * @param\toptions\t\tOptions for the stream encryption.\n\t * @returns An object containing:\n\t * \t- a new instance of `crypto.Cipher` allowing you to add listeners to the `cipher` encryption process.\n\t * \t- the actual `encrypt` callback that must be called and awaited in order to start the encryption process.\n\t */\n\tstatic hybridEncrypt(\n\t\tsecret\t\t: CoerceToUint8ArrayInput,\n\t\tpublicKey\t: crypto.RsaPublicKey | crypto.RsaPrivateKey | crypto.KeyLike,\n\t\toptions\t\t: Cph.Stream.Hybrid.EncryptOptions,\n\t): Cph.Stream.Hybrid.EncryptReturnType\n\t{\n\t\toptions.algorithm ||= Cipher.DEFAULT_ALGORITHM.stream\n\n\t\tconst {\n\t\t\tKey, IV,\n\t\t\toptions: { algorithm, input, output },\n\t\t} = Cipher.newKeyIV<Cph.Stream.Hybrid.EncryptResolvedOptions>( secret, options )\n\n\t\tconst encryptedKey = (\n\t\t\tcrypto.publicEncrypt( publicKey, Buffer.concat( [ Key, IV ] ) )\n\t\t)\n\n\t\tconst cipher = crypto.createCipheriv( algorithm, Key, IV )\n\t\tconst encrypt = () => (\n\t\t\tCipher.stream( {\n\t\t\t\tcipher, input, output, encryptedKey\n\t\t\t} )\n\t\t)\n\n\t\treturn { cipher, encrypt }\n\t}\n\n\n\t/**\n\t * Decrypt a `Readable` to a `Writable` Stream with hybrid Decryption.\n\t * \n\t * The `Readable` Stream could be 'in-memory buffer' or 'file' based.\n\t *\n\t * @param\tprivateKey\tThe RSA private key used to decrypt the symmetric key.\n\t * @param\toptions\t\tOptions for the stream decryption.\n\t * @returns A new Promise that resolves when Key IV extraction completes returning an object containing:\n\t * \t- a new instance of `crypto.Decipher` allowing you to add listeners to the `decipher` decryption process.\n\t * \t- the actual `decrypt` callback that must be called and awaited in order to start the decryption process.\n\t */\n\tstatic hybridDecrypt(\n\t\tprivateKey\t: crypto.RsaPrivateKey | crypto.KeyLike,\n\t\toptions\t\t: Cph.Stream.Hybrid.DecryptOptions,\n\t): Promise<Cph.Stream.Hybrid.DecryptReturnType>\n\t{\n\t\toptions.algorithm ||= Cipher.DEFAULT_ALGORITHM.stream\n\n\t\tconst {\n\t\t\tinput, output, algorithm, length, rsaKeyLength,\n\t\t} = Cipher.resolveOptions<Cph.Stream.Hybrid.DecryptResolvedOptions>( options )\n\n\t\treturn (\n\t\t\tCipher.extractKeyIV( input, rsaKeyLength )\n\t\t\t\t.then( ( [ encryptedKeyIV, input ] ) => {\n\t\t\t\t\tconst KeyIV\t\t= crypto.privateDecrypt( privateKey, encryptedKeyIV )\n\t\t\t\t\tconst Key\t\t= KeyIV.subarray( 0, length )\n\t\t\t\t\tconst IV\t\t= KeyIV.subarray( length )\n\t\t\t\t\tconst decipher\t= crypto.createDecipheriv( algorithm, Key, IV )\n\t\n\t\t\t\t\tconst decrypt = () => (\n\t\t\t\t\t\tCipher.decipherStream(\n\t\t\t\t\t\t\t{ decipher, input, output }\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\n\t\t\t\t\treturn { decipher, decrypt }\n\t\t\t\t} )\n\t\t)\n\t}\n\n\n\t/**\n\t * Handle pipe flow to encrypt a Stream.\n\t * \n\t * @param\toptions Required parameters.\n\t * @returns A new Promise that resolves `void` once stream is completed.\n\t */\n\tprivate static stream( options: StreamEncryptOptions )\n\t{\n\t\tconst {\n\t\t\tcipher, encryptedKey,\n\t\t\tinput, output\n\t\t} = options\n\n\t\treturn (\n\t\t\tnew Promise<void>( ( resolve, reject ) => {\n\t\t\t\tcipher.on( 'error', reject )\n\t\t\t\tinput.on( 'error', reject )\n\t\t\t\toutput.on( 'error', reject )\n\t\t\t\toutput.on( 'finish', resolve )\n\t\t\n\t\t\t\toutput.write( encryptedKey )\n\t\t\t\tinput.pipe( cipher ).pipe( output )\n\t\t\t} )\n\t\t)\n\t}\n\n\n\t/**\n\t * Handle pipe flow to decrypt a Stream.\n\t * \n\t * @param\toptions Required parameters.\n\t * @returns A new Promise that resolves `void` once stream is completed.\n\t */\n\tprivate static decipherStream( options: StreamDecryptOptions )\n\t{\n\t\tconst {\n\t\t\tdecipher, input, output,\n\t\t} = options\n\n\t\treturn (\n\t\t\tnew Promise<void>( ( resolve, reject ) => {\n\t\t\t\tdecipher.on( 'error', reject )\n\t\t\t\tinput.on( 'error', reject )\n\t\t\t\toutput.on( 'error', reject )\n\t\t\t\toutput.on( 'finish', resolve )\n\n\t\t\t\tinput.pipe( decipher ).pipe( output )\n\t\t\t} )\n\t\t)\n\t}\n\n\n\t/**\n\t * Extract the Cipher Encrypted Symmetric Key and Initialization Vector from an encrypted `Readable` Stream.\n\t *\n\t * @param\tinput\t\tThe `Readable` Stream.\n\t * @param\tkeyLength\tThe encrypted key length in bytes. This is used to properly extract the encrypted Cipher Key and Initialization Vector.\n\t * @returns\tA new Promise that resolve a tuple containing the Cipher Encrypted Symmetric Key and Initialization Vector once fulfilled.\n\t */\n\tprivate static extractKeyIV(\n\t\tinput\t\t: Readable,\n\t\tkeyLength\t: number,\n\t)\n\t{\n\t\treturn (\n\t\t\tnew Promise<[ KeyIV: Buffer, input: Transform ]>( ( resolve, reject ) => {\n\t\t\t\tlet KeyIV\t\t= Buffer.alloc( 0 )\n\t\t\t\tlet bytesRead\t= 0\n\t\t\t\tlet resolved\t= false\n\n\t\t\t\tconst transform = new Transform( {\n\t\t\t\t\tasync transform( chunk: Buffer, encoding, callback )\n\t\t\t\t\t{\n\n\t\t\t\t\t\tif ( KeyIV.length < keyLength ) {\n\t\t\t\t\t\t\tKeyIV = Buffer.concat( [ KeyIV, chunk ] )\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbytesRead += chunk.length\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * `KeyIV` length may exceed the `keyLength`.\n\t\t\t\t\t\t * This may occurs when the received chunk length is not a multiple of the `keyLength`.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * In that case the chunk will contain mixed content:\n\t\t\t\t\t\t * - end of the `KeyIV`.\n\t\t\t\t\t\t * - begin of the actual encrypted data.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * For a proper data handling we need to:\n\t\t\t\t\t\t * - cut off the `KeyIV` to `keyLength` bytes.\n\t\t\t\t\t\t * - recover and push the byte loss to the next piped destination.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif ( KeyIV.length > keyLength ) {\n\t\t\t\t\t\t\tconst bytesLoss\t= Math.max( 0, KeyIV.length - keyLength )\n\t\t\t\t\t\t\tKeyIV\t\t\t= KeyIV.subarray( 0, keyLength )\n\t\t\t\t\t\t\tconst subchunk\t= chunk.subarray( bytesLoss * -1 )\n\n\t\t\t\t\t\t\tif ( ! resolved ) {\n\t\t\t\t\t\t\t\tresolve( [ KeyIV, this ] )\n\t\t\t\t\t\t\t\tresolved = true\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t/**\n\t\t\t\t\t\t\t * Push to the next piped destination.\n\t\t\t\t\t\t\t */\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tthis.push( subchunk, encoding )\n\n\t\t\t\t\t\t\treturn callback()\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * `KeyIV` has been read.\n\t\t\t\t\t\t * The Received chunk can now be pushed to the next piped destination.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif ( bytesRead > keyLength ) {\n\t\t\t\t\t\t\tif ( ! resolved ) {\n\t\t\t\t\t\t\t\tresolve( [ KeyIV, this ] )\n\t\t\t\t\t\t\t\tresolved = true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t/**\n\t\t\t\t\t\t\t * Push to the next piped destination.\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\tthis.push( chunk, encoding )\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn callback()\n\t\t\t\t\t},\n\t\t\t\t\tfinal( callback )\n\t\t\t\t\t{\n\t\t\t\t\t\tif ( KeyIV.length < keyLength ) {\n\t\t\t\t\t\t\treturn callback(\n\t\t\t\t\t\t\t\tnew Error( 'The extracted KeyIV length is less than the expected length.' )\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn callback()\n\t\t\t\t\t},\n\t\t\t\t} )\n\n\t\t\t\ttransform.on( 'error', reject )\n\t\t\t\tinput.on( 'error', error => {\n\t\t\t\t\ttransform.destroy( error )\n\t\t\t\t\treject( error )\n\t\t\t\t} )\n\t\t\t\tinput.pipe( transform )\n\t\t\t} )\n\t\t)\n\t}\n\n\n\t/**\n\t * Generates a `Scrypt` Symmetric Key and the Initialization Vector with the given options.\n\t * \n\t * @param\tsecret\tThe secret key.\n\t * @param\toptions\t( Optional ) Additional options.\n\t * \n\t * @returns An object with the generated `Key`, `IV`, `salt` and resolved `options`. \n\t */\n\tstatic newKeyIV<T extends Cph.ResolvedOptions = Cph.ResolvedOptions>(\n\t\tsecret\t: CoerceToUint8ArrayInput,\n\t\toptions\t: Cph.Options = {},\n\t)\n\t{\n\t\tconst _secret\t= coerceToUint8Array( secret )\n\t\tconst _options\t= Cipher.resolveOptions<T>( options )\n\t\tconst salt\t\t= crypto.randomBytes( _options.salt )\n\t\tconst Key\t\t= crypto.scryptSync( _secret, salt, _options.length )\n\t\tconst IV\t\t= crypto.randomBytes( _options.iv )\n\t\tconst AAD\t\t= _options.aad || crypto.scryptSync( Key, salt, _options.aadLength )\n\n\t\treturn { options: _options, Key, IV, AAD, salt }\n\t}\n\n\n\t/**\n\t * Resolves the given `options` with `Cipher` defaults and constraints.\n\t * \n\t * @param options ( Optional ) Additional options.\n\t * @returns The given `options` with `Cipher` defaults and constraints.\n\t */\n\tstatic resolveOptions<\n\t\tT extends Cph.ResolvedOptions = Cph.ResolvedOptions\n\t>( options: Cph.Options = {} ): T\n\t{\n\t\tconst _options = { ...options } as T\n\n\t\tif ( _options.aad ) {\n\t\t\t_options.aad = coerceToUint8Array( _options.aad )\n\t\t}\n\n\t\t_options.salt\t\t||= Cipher.SALT_LENGTH.default\n\t\t_options.authTag\t||= Cipher.AUTH_TAG_LENGTH.default\n\t\t_options.aadLength\t= _options.aad?.length || _options.aadLength || Cipher.AAD_LENGTH.default\n\t\t_options.salt\t\t= Math.min( Math.max( _options.salt, Cipher.SALT_LENGTH.min ), Cipher.SALT_LENGTH.max )\n\t\t_options.authTag\t= Math.min( Math.max( _options.authTag, Cipher.AUTH_TAG_LENGTH.min ), Cipher.AUTH_TAG_LENGTH.max )\n\t\tif ( ! _options.aad ) {\n\t\t\t_options.aadLength\t= Math.min( Math.max( _options.aadLength, Cipher.AAD_LENGTH.min ), Cipher.AAD_LENGTH.max )\n\t\t}\n\n\t\tconst { keyLength, algorithm } = Cipher.getKeyLength( options.algorithm )\n\n\t\t_options.algorithm\t= algorithm\n\t\t_options.length\t\t= keyLength\n\t\t_options.iv\t\t\t= Cipher.getIVLength( algorithm, options )\n\n\t\treturn _options\n\t}\n\n\n\t/**\n\t * Get the Initialization Vector length based on the given algorithm.\n\t * \n\t * @param\talgorithm The algorithm in use.\n\t * @param\toptions ( Optional ) Additional options. \n\t * @returns\tThe Initialization Vector length based on the given algorithm\n\t */\n\tprivate static getIVLength(\n\t\talgorithm\t: Cph.Options[ 'algorithm' ] = Cipher.DEFAULT_ALGORITHM.buffer,\n\t\toptions\t\t: Cph.Options = {},\n\t)\n\t{\n\t\tswitch ( algorithm ) {\n\t\t\tcase 'aes-128-ccm':\n\t\t\tcase 'aes-128-ocb':\n\t\t\tcase 'aes-192-ccm':\n\t\t\tcase 'aes-192-ocb':\n\t\t\tcase 'aes-256-ccm':\n\t\t\tcase 'aes-256-ocb':\n\t\t\t\treturn 8\n\t\t\tcase 'chacha20-poly1305':\n\t\t\t\treturn 12\n\t\t\tdefault:\n\t\t\t\treturn (\n\t\t\t\t\tMath.min(\n\t\t\t\t\t\tMath.max(\n\t\t\t\t\t\t\toptions.iv || Cipher.IV_LENGTH.default,\n\t\t\t\t\t\t\tCipher.IV_LENGTH.min\n\t\t\t\t\t\t), Cipher.IV_LENGTH.max\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t}\n\t}\n\n\n\t/**\n\t * Ensure correct key length based on the given algorithm.\n\t *\n\t * @param\talgorithm The AES algorithm name.\n\t * @returns\tAn object with validated `algorithm` and `keyLength`.\n\t */\n\tprivate static getKeyLength(\n\t\talgorithm: Cph.Options[ 'algorithm' ] = Cipher.DEFAULT_ALGORITHM.buffer\n\t)\n\t{\n\t\tswitch ( algorithm ) {\n\t\t\tcase 'chacha20-poly1305':\n\t\t\t\treturn {\n\t\t\t\t\talgorithm: algorithm,\n\t\t\t\t\tkeyLength: 256 / 8,\n\t\t\t\t} as const\n\t\t\tcase 'aes-128-cbc':\n\t\t\tcase 'aes-128-ccm':\n\t\t\tcase 'aes-128-gcm':\n\t\t\tcase 'aes-128-ocb':\n\t\t\t\treturn {\n\t\t\t\t\talgorithm: algorithm,\n\t\t\t\t\tkeyLength: 128 / 8, // AES-128 needs a 128 bit (16 bytes)\n\t\t\t\t} as const\n\t\t\tcase 'aes-192-cbc':\n\t\t\tcase 'aes-192-ccm':\n\t\t\tcase 'aes-192-gcm':\n\t\t\tcase 'aes-192-ocb':\n\t\t\t\treturn {\n\t\t\t\t\talgorithm: algorithm,\n\t\t\t\t\tkeyLength: 192 / 8, // AES-192 needs a 192 bit (24 bytes)\n\t\t\t\t} as const\n\t\t\tcase 'aes-256-cbc':\n\t\t\tcase 'aes-256-ccm':\n\t\t\tcase 'aes-256-gcm':\n\t\t\tcase 'aes-256-ocb':\n\t\t\tdefault:\n\t\t\t\treturn {\n\t\t\t\t\talgorithm: algorithm,\n\t\t\t\t\tkeyLength: 256 / 8, // AES-256 needs a 256 bit (32 bytes)\n\t\t\t\t} as const\n\t\t}\n\t}\n\n\n\t/**\n\t * Check if the given algorithm is a Cipher AES-GCM algorithm.\n\t * \n\t * @param algorithm The AES Algorithm to check.\n\t * @returns `true` if the given algorithm is a Cipher AES-GCM algorithm. `false` otherwise.\n\t */\n\tstatic isGCM( algorithm: Cph.AesAlgorithm ): algorithm is crypto.CipherGCMTypes\n\t{\n\t\treturn (\n\t\t\talgorithm === 'aes-128-gcm' ||\n\t\t\talgorithm === 'aes-192-gcm' ||\n\t\t\talgorithm === 'aes-256-gcm'\n\t\t)\n\t}\n\n\n\t/**\n\t * Check if the given algorithm is a Cipher AES-CCM algorithm.\n\t * \n\t * @param algorithm The AES Algorithm to check.\n\t * @returns `true` if the given algorithm is a Cipher AES-CCM algorithm. `false` otherwise.\n\t */\n\tstatic isCCM( algorithm: Cph.AesAlgorithm ): algorithm is crypto.CipherCCMTypes\n\t{\n\t\treturn (\n\t\t\talgorithm === 'aes-128-ccm' ||\n\t\t\talgorithm === 'aes-192-ccm' ||\n\t\t\talgorithm === 'aes-256-ccm' ||\n\t\t\talgorithm === 'chacha20-poly1305'\n\t\t)\n\t}\n\n\n\t/**\n\t * Check if the given algorithm is a Cipher AES-OCB algorithm.\n\t * \n\t * @param algorithm The AES Algorithm to check.\n\t * @returns `true` if the given algorithm is a Cipher AES-OCB algorithm. `false` otherwise.\n\t */\n\tstatic isOCB( algorithm: Cph.AesAlgorithm ): algorithm is crypto.CipherOCBTypes\n\t{\n\t\treturn (\n\t\t\talgorithm === 'aes-128-ocb' ||\n\t\t\talgorithm === 'aes-192-ocb' ||\n\t\t\talgorithm === 'aes-256-ocb'\n\t\t)\n\t}\n\n\n\t/**\n\t * Check if the given algorithm is a Cipher AES-CBC algorithm.\n\t * \n\t * @param algorithm The AES Algorithm to check.\n\t * @returns `true` if the given algorithm is a Cipher AES-CBC algorithm. `false` otherwise.\n\t */\n\tstatic isCBC( algorithm: Cph.AesAlgorithm ): algorithm is Cph.CBCTypes\n\t{\n\t\treturn (\n\t\t\talgorithm === 'aes-128-cbc' ||\n\t\t\talgorithm === 'aes-192-cbc' ||\n\t\t\talgorithm === 'aes-256-cbc'\n\t\t)\n\t}\n}"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import m from'crypto';import {Transform}from'stream';import {coerceToUint8Array}from'@alessiofrittoli/crypto-buffer/coercion';var t=class t{static encrypt(r,e,o={}){let a=coerceToUint8Array(r),{salt:c,Key:s,IV:n,AAD:p,options:{algorithm:i,authTag:h}}=t.newKeyIV(e,o);if(t.isCBC(i)){let T=m.createCipheriv(i,s,n),d=Buffer.concat([T.update(a),T.final()]);return Buffer.concat([c,n,d])}let y=m.createCipheriv(i,s,n,{authTagLength:h});t.isCCM(i)&&y.setAAD(p,{plaintextLength:a.length}),(t.isGCM(i)||t.isOCB(i))&&y.setAAD(p);let u=Buffer.concat([y.update(a),y.final()]),l=y.getAuthTag();return Buffer.concat([c,n,p,l,u])}static decrypt(r,e,o={}){let a=coerceToUint8Array(r),c=coerceToUint8Array(e),s=t.resolveOptions(o),{algorithm:n}=s,p=a.subarray(0,s.salt);a=a.subarray(s.salt);let i=a.subarray(0,s.iv);a=a.subarray(s.iv);let h=m.scryptSync(c,p,s.length);if(t.isCBC(n)){let f=m.createDecipheriv(s.algorithm,h,i);return Buffer.concat([f.update(a),f.final()])}let y=s.aadLength,u=s.authTag,l=a.subarray(0,y);a=a.subarray(y);let T=a.subarray(0,u);a=a.subarray(u);let d=m.createDecipheriv(n,h,i,{authTagLength:u});return t.isCCM(n)&&d.setAAD(l,{plaintextLength:a.length}),(t.isGCM(n)||t.isOCB(n))&&d.setAAD(l),d.setAuthTag(T),Buffer.concat([d.update(a),d.final()])}static streamEncrypt(r,e){e.algorithm||(e.algorithm=t.DEFAULT_ALGORITHM.stream);let{Key:o,IV:a,options:{input:c,output:s,algorithm:n,salt:p,iv:i,authTag:h}}=t.newKeyIV(r,e),y=t.encrypt(Buffer.concat([o,a]),r,{algorithm:n,salt:p,iv:i,authTag:h}),u=m.createCipheriv(n,o,a);return {cipher:u,encrypt:()=>t.stream({cipher:u,input:c,output:s,encryptedKey:y})}}static streamDecrypt(r,e){e.algorithm||(e.algorithm=t.DEFAULT_ALGORITHM.stream);let{input:o,output:a,algorithm:c,salt:s,iv:n,authTag:p,length:i}=t.resolveOptions(e),h=i+n+s+n+p;return t.extractKeyIV(o,h).then(([y,u])=>{if(u.errored)throw u.errored;let l=t.decrypt(y,r,{algorithm:c,salt:s,iv:n,authTag:p}),T=l.subarray(0,i),d=l.subarray(i),f=m.createDecipheriv(c,T,d);return {decipher:f,decrypt:()=>t.decipherStream({decipher:f,input:u,output:a})}})}static hybridEncrypt(r,e,o){o.algorithm||(o.algorithm=t.DEFAULT_ALGORITHM.stream);let{Key:a,IV:c,options:{algorithm:s,input:n,output:p}}=t.newKeyIV(r,o),i=m.publicEncrypt(e,Buffer.concat([a,c])),h=m.createCipheriv(s,a,c);return {cipher:h,encrypt:()=>t.stream({cipher:h,input:n,output:p,encryptedKey:i})}}static hybridDecrypt(r,e){e.algorithm||(e.algorithm=t.DEFAULT_ALGORITHM.stream);let{input:o,output:a,algorithm:c,length:s,rsaKeyLength:n}=t.resolveOptions(e);return t.extractKeyIV(o,n).then(([p,i])=>{let h=m.privateDecrypt(r,p),y=h.subarray(0,s),u=h.subarray(s),l=m.createDecipheriv(c,y,u);return {decipher:l,decrypt:()=>t.decipherStream({decipher:l,input:i,output:a})}})}static stream(r){let{cipher:e,encryptedKey:o,input:a,output:c}=r;return new Promise((s,n)=>{e.on("error",n),a.on("error",n),c.on("error",n),c.on("finish",s),c.write(o),a.pipe(e).pipe(c);})}static decipherStream(r){let{decipher:e,input:o,output:a}=r;return new Promise((c,s)=>{e.on("error",s),o.on("error",s),a.on("error",s),a.on("finish",c),o.pipe(e).pipe(a);})}static extractKeyIV(r,e){return new Promise((o,a)=>{let c=Buffer.alloc(0),s=0,n=false,p=new Transform({async transform(i,h,y){if(c.length<e&&(c=Buffer.concat([c,i])),s+=i.length,c.length>e){let u=Math.max(0,c.length-e);c=c.subarray(0,e);let l=i.subarray(u*-1);return n||(o([c,this]),n=true),this.push(l,h),y()}return s>e&&(n||(o([c,this]),n=true),this.push(i,h)),y()},final(i){return c.length<e?i(new Error("The extracted KeyIV length is less than the expected length.")):i()}});p.on("error",a),r.on("error",i=>{p.destroy(i),a(i);}),r.pipe(p);})}static newKeyIV(r,e={}){let o=coerceToUint8Array(r),a=t.resolveOptions(e),c=m.randomBytes(a.salt),s=m.scryptSync(o,c,a.length),n=m.randomBytes(a.iv),p=a.aad||m.scryptSync(s,c,a.aadLength);return {options:a,Key:s,IV:n,AAD:p,salt:c}}static resolveOptions(r={}){let e={...r};e.aad&&(e.aad=coerceToUint8Array(e.aad)),e.salt||(e.salt=t.SALT_LENGTH.default),e.authTag||(e.authTag=t.AUTH_TAG_LENGTH.default),e.aadLength=e.aad?.length||e.aadLength||t.AAD_LENGTH.default,e.salt=Math.min(Math.max(e.salt,t.SALT_LENGTH.min),t.SALT_LENGTH.max),e.authTag=Math.min(Math.max(e.authTag,t.AUTH_TAG_LENGTH.min),t.AUTH_TAG_LENGTH.max),e.aad||(e.aadLength=Math.min(Math.max(e.aadLength,t.AAD_LENGTH.min),t.AAD_LENGTH.max));let{keyLength:o,algorithm:a}=t.getKeyLength(r.algorithm);return e.algorithm=a,e.length=o,e.iv=t.getIVLength(a,r),e}static getIVLength(r=t.DEFAULT_ALGORITHM.buffer,e={}){switch(r){case "aes-128-ccm":case "aes-128-ocb":case "aes-192-ccm":case "aes-192-ocb":case "aes-256-ccm":case "aes-256-ocb":return 8;case "chacha20-poly1305":return 12;default:return Math.min(Math.max(e.iv||t.IV_LENGTH.default,t.IV_LENGTH.min),t.IV_LENGTH.max)}}static getKeyLength(r=t.DEFAULT_ALGORITHM.buffer){switch(r){case "chacha20-poly1305":return {algorithm:r,keyLength:256/8};case "aes-128-cbc":case "aes-128-ccm":case "aes-128-gcm":case "aes-128-ocb":return {algorithm:r,keyLength:128/8};case "aes-192-cbc":case "aes-192-ccm":case "aes-192-gcm":case "aes-192-ocb":return {algorithm:r,keyLength:192/8};case "aes-256-cbc":case "aes-256-ccm":case "aes-256-gcm":case "aes-256-ocb":default:return {algorithm:r,keyLength:256/8}}}static isGCM(r){return r==="aes-128-gcm"||r==="aes-192-gcm"||r==="aes-256-gcm"}static isCCM(r){return r==="aes-128-ccm"||r==="aes-192-ccm"||r==="aes-256-ccm"||r==="chacha20-poly1305"}static isOCB(r){return r==="aes-128-ocb"||r==="aes-192-ocb"||r==="aes-256-ocb"}static isCBC(r){return r==="aes-128-cbc"||r==="aes-192-cbc"||r==="aes-256-cbc"}};t.SALT_LENGTH={min:16,max:64,default:32},t.IV_LENGTH={min:8,max:32,default:16},t.AUTH_TAG_LENGTH={min:4,max:16,default:16},t.AAD_LENGTH={min:16,max:128,default:32},t.DEFAULT_ALGORITHM={buffer:"aes-256-gcm",stream:"aes-256-cbc"},t.ALGORITHMS=["aes-128-cbc","aes-128-ccm","aes-128-gcm","aes-128-ocb","aes-192-cbc","aes-192-ccm","aes-192-gcm","aes-192-ocb","aes-256-cbc","aes-256-ccm","aes-256-gcm","aes-256-ocb","chacha20-poly1305"];var A=t;export{A as Cipher};//# sourceMappingURL=index.mjs.map
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["_Cipher","data","secret","options","_data","coerceToUint8Array","salt","Key","IV","AAD","algorithm","authTagLength","cipher","crypto","encrypted","authTag","_secret","_options","decipher","AADLength","input","output","iv","encryptedKey","length","keyIvLength","encryptedKeyIV","KeyIV","publicKey","privateKey","rsaKeyLength","resolve","reject","keyLength","bytesRead","resolved","transform","Transform","chunk","encoding","callback","bytesLoss","subchunk","error","Cipher"],"mappings":"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","file":"index.mjs","sourcesContent":["import crypto from 'crypto'\nimport { Transform } from 'stream'\nimport type { Readable, Writable } from 'stream'\nimport { coerceToUint8Array, type CoerceToUint8ArrayInput } from '@alessiofrittoli/crypto-buffer/coercion'\n\nimport type { Cph } from './types'\n\n\n\n/**\n * INTERNAL USE ONLY\n */\ninterface StreamEncryptOptions\n{\n\tcipher\t\t: crypto.Cipher\n\tencryptedKey: Buffer\n\tinput\t\t: Readable\n\toutput\t\t: Writable\n}\n\n\n/**\n * INTERNAL USE ONLY\n */\ninterface StreamDecryptOptions\n{\n\tdecipher\t: crypto.Decipher\n\tinput\t\t: Readable\n\toutput\t\t: Writable\n}\n\n\n/**\n * Utility class for AES encryption and decryption following [NIST SP 800-38D](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf) standard reccomendations.\n */\nexport class Cipher\n{\n\t/**\n\t * Cipher default `salt` lengths.\n\t */\n\tstatic readonly SALT_LENGTH = {\n\t\tmin\t\t: 16,\n\t\tmax\t\t: 64,\n\t\tdefault\t: 32,\n\t} as const\n\n\n\t/**\n\t * Cipher default `IV` lengths.\n\t */\n\tstatic readonly IV_LENGTH = {\n\t\tmin\t\t: 8,\n\t\tmax\t\t: 32,\n\t\tdefault\t: 16,\n\t} as const\n\n\n\t/**\n\t * Cipher default `Auth Tag` lengths.\n\t */\n\tstatic readonly AUTH_TAG_LENGTH = {\n\t\tmin\t\t: 4,\n\t\tmax\t\t: 16,\n\t\tdefault\t: 16,\n\t} as const\n\t\n\t\n\t/**\n\t * Cipher default `Additional Authenticated Data` lengths.\n\t */\n\tstatic readonly AAD_LENGTH = {\n\t\tmin\t\t: 16,\n\t\tmax\t\t: 128,\n\t\tdefault\t: 32,\n\t} as const\n\t\n\n\t/**\n\t * Default AES algorithms used based on functionality.\n\t */\n\tstatic readonly DEFAULT_ALGORITHM = {\n\t\tbuffer: 'aes-256-gcm',\n\t\tstream: 'aes-256-cbc',\n\t} as const\n\n\n\t/**\n\t * Supported AES algorithms.\n\t */\n\tstatic readonly ALGORITHMS: Cph.AesAlgorithm[] = [\n\t\t'aes-128-cbc', 'aes-128-ccm', 'aes-128-gcm', 'aes-128-ocb',\n\t\t'aes-192-cbc', 'aes-192-ccm', 'aes-192-gcm', 'aes-192-ocb',\n\t\t'aes-256-cbc', 'aes-256-ccm', 'aes-256-gcm', 'aes-256-ocb',\n\t\t'chacha20-poly1305'\n\t] as const\n\n\n\t/**\n\t * Encrypt in-memory data buffer.\n\t *\n\t * ⚠️ This is not suitable for large data. Use {@link Cipher.streamEncrypt()} or {@link Cipher.hybridEncrypt()} methods for large data encryption.\n\t *\n\t * @param\tdata\tThe data to encrypt.\n\t * @param\tsecret\tThe secret key used to encrypt the `data`.\n\t * @param\toptions\t( Optional ) Additional options.\n\t * @returns\tThe encrypted result Buffer.\n\t */\n\tstatic encrypt(\n\t\tdata\t: CoerceToUint8ArrayInput,\n\t\tsecret\t: CoerceToUint8ArrayInput,\n\t\toptions\t: Cph.Options = {},\n\t): Buffer\n\t{\n\t\tconst _data = coerceToUint8Array( data )\n\n\t\tconst {\n\t\t\tsalt, Key, IV, AAD,\n\t\t\toptions: { algorithm, authTag: authTagLength },\n\t\t} = Cipher.newKeyIV( secret, options )\n\n\t\tif ( Cipher.isCBC( algorithm ) ) {\n\t\t\tconst cipher\t= crypto.createCipheriv( algorithm, Key, IV )\n\t\t\tconst encrypted\t= Buffer.concat( [ cipher.update( _data ), cipher.final() ] )\n\n\t\t\treturn Buffer.concat( [ salt, IV, encrypted ] )\n\t\t}\n\n\n\t\tconst cipher = (\n\t\t\tcrypto.createCipheriv(\n\t\t\t\t// @ts-expect-error `crypto.createCipheriv` cannot infer the correct overload based on the given union type algorithm.\n\t\t\t\talgorithm, Key, IV, { authTagLength }\n\t\t\t)\n\t\t)\n\t\t\n\t\t\n\t\tif ( Cipher.isCCM( algorithm ) ) {\n\t\t\t// AES-CCM requires `plaintextLength`\n\t\t\tcipher.setAAD( AAD, { plaintextLength: _data.length } )\n\t\t}\n\n\t\tif ( Cipher.isGCM( algorithm ) || Cipher.isOCB( algorithm ) ) {\n\t\t\t// AES-GCM and AES-OCB doesn't require `plaintextLength`\n\t\t\tcipher.setAAD( AAD )\n\t\t}\n\n\t\tconst encrypted\t= Buffer.concat( [ cipher.update( _data ), cipher.final() ] )\n\t\tconst authTag\t= cipher.getAuthTag()\n\n\t\treturn Buffer.concat( [ salt, IV, AAD, authTag, encrypted ] )\n\t}\n\n\n\t/**\n\t * Decrypt in-memory data buffer.\n\t *\n\t * ⚠️ This is not suitable for large data. Use {@link Cipher.streamDecrypt()} or {@link Cipher.hybridDecrypt()} methods for large data decryption.\n\t *\n\t * @param\tdata\tThe data to decrypt.\n\t * @param\tsecret\tThe secret key used to decrypt the `data`.\n\t * @param\toptions\t( Optional ) Additional options. Must be the same used while encrypting data.\n\t * @returns\tThe decrypted data Buffer.\n\t */\n\tstatic decrypt(\n\t\tdata\t: CoerceToUint8ArrayInput,\n\t\tsecret\t: CoerceToUint8ArrayInput,\n\t\toptions\t: Cph.Options = {},\n\t): Buffer\n\t{\n\t\tlet _data\t\t\t= coerceToUint8Array( data )\n\t\tconst _secret\t\t= coerceToUint8Array( secret )\n\t\tconst _options\t\t= Cipher.resolveOptions( options )\n\t\tconst { algorithm }\t= _options\n\n\t\tconst salt\t\t= _data.subarray( 0, _options.salt )\n\t\t_data\t\t\t= _data.subarray( _options.salt )\n\t\tconst IV\t\t= _data.subarray( 0, _options.iv )\n\t\t_data\t\t\t= _data.subarray( _options.iv )\n\t\tconst Key\t\t= crypto.scryptSync( _secret, salt, _options.length )\n\n\t\tif ( Cipher.isCBC( algorithm ) ) {\n\t\t\tconst decipher = (\n\t\t\t\tcrypto.createDecipheriv( _options.algorithm, Key, IV )\n\t\t\t)\n\n\t\t\treturn (\n\t\t\t\tBuffer.concat( [ decipher.update( _data ), decipher.final() ] )\n\t\t\t)\n\t\t}\n\n\t\tconst AADLength\t\t= _options.aadLength\n\t\tconst authTagLength\t= _options.authTag\n\t\tconst AAD\t\t\t= _data.subarray( 0, AADLength )\n\t\t_data\t\t\t\t= _data.subarray( AADLength )\n\t\tconst authTag\t\t= _data.subarray( 0, authTagLength )\n\t\t_data\t\t\t\t= _data.subarray( authTagLength )\n\n\n\t\tconst decipher = (\n\t\t\tcrypto.createDecipheriv(\n\t\t\t\t// @ts-expect-error `crypto.createDecipheriv` cannot infer the correct overload based on the given union type algorithm.\n\t\t\t\talgorithm, Key, IV, { authTagLength }\n\t\t\t)\n\t\t)\n\n\t\tif ( Cipher.isCCM( algorithm ) ) {\n\t\t\t// AES-CCM requires `plaintextLength`\n\t\t\tdecipher.setAAD( AAD, { plaintextLength: _data.length } )\n\t\t}\n\n\t\tif ( Cipher.isGCM( algorithm ) || Cipher.isOCB( algorithm ) ) {\n\t\t\t// AES-GCM and AES-OCB doesn't require `plaintextLength`\n\t\t\tdecipher.setAAD( AAD )\n\t\t}\n\n\t\tdecipher.setAuthTag( authTag )\n\t\n\t\treturn (\n\t\t\tBuffer.concat( [ decipher.update( _data ), decipher.final() ] )\n\t\t)\n\n\t}\n\n\n\t/**\n\t * Encrypt a `Readable` to a `Writable` Stream.\n\t * \n\t * The `Readable` Stream could be 'in-memory buffer' or 'file' based.\n\t * \n\t * @param\tsecret\tThe secret key used to encrypt the `data`.\n\t * @param\toptions Additional options.\n\t * @returns An object containing:\n\t * \t- a new instance of `crypto.Cipher` allowing you to add listeners to the `cipher` encryption process.\n\t * \t- the actual `encrypt` callback that must be called and awaited in order to start the encryption process.\n\t */\n\tstatic streamEncrypt(\n\t\tsecret\t: CoerceToUint8ArrayInput,\n\t\toptions\t: Cph.Stream.Symmetric.EncryptOptions,\n\t): Cph.Stream.Symmetric.EncryptReturnType\n\t{\n\t\toptions.algorithm ||= Cipher.DEFAULT_ALGORITHM.stream\n\n\t\tconst {\n\t\t\tKey, IV, options: { input, output, algorithm, salt, iv, authTag },\n\t\t} = Cipher.newKeyIV<Cph.Stream.Symmetric.EncryptResolvedOptions>( secret, options )\n\n\t\tconst encryptedKey = (\n\t\t\tCipher.encrypt( Buffer.concat( [ Key, IV ] ), secret, { algorithm, salt, iv, authTag } )\n\t\t)\n\n\t\tconst cipher = crypto.createCipheriv( algorithm, Key, IV )\n\t\tconst encrypt = () => (\n\t\t\tCipher.stream( {\n\t\t\t\tcipher, input, output, encryptedKey\n\t\t\t} )\n\t\t)\n\n\t\treturn { cipher, encrypt }\n\t}\n\n\n\t/**\n\t * Decrypt a `Readable` to a `Writable` Stream.\n\t * \n\t * The `Readable` Stream could be 'in-memory buffer' or 'file' based.\n\t * \n\t * @param\tsecret\tThe secret key used to encrypt the `data`.\n\t * @param\toptions Additional options.\n\t * @returns A new Promise that resolves when Key IV extraction completes returning an object containing:\n\t * \t- a new instance of `crypto.Decipher` allowing you to add listeners to the `decipher` decryption process.\n\t * \t- the actual `decrypt` callback that must be called and awaited in order to start the decryption process.\n\t */\n\tstatic streamDecrypt(\n\t\tsecret\t: CoerceToUint8ArrayInput,\n\t\toptions\t: Cph.Stream.Symmetric.DecryptOptions,\n\t): Promise<Cph.Stream.Symmetric.DecryptReturnType>\n\t{\n\t\toptions.algorithm ||= Cipher.DEFAULT_ALGORITHM.stream\n\n\t\tconst {\n\t\t\tinput, output, algorithm, salt, iv, authTag, length\n\t\t} = Cipher.resolveOptions<Cph.Stream.Symmetric.DecryptResolvedOptions>( options )\n\n\t\tconst keyIvLength = (\n\t\t\tlength + iv\n\t\t\t+ salt + iv + authTag\n\t\t)\n\n\t\treturn (\n\t\t\tCipher.extractKeyIV( input, keyIvLength )\n\t\t\t\t.then( ( [ encryptedKeyIV, input ] ) => {\n\t\t\t\t\t/**\n\t\t\t\t\t * Check if input has error and re-throw if so.\n\t\t\t\t\t * This is required since `.on( 'error' )` listeners attached in\n\t\t\t\t\t * `Cipher.decipherStream()` get attached too late (error event already emitted).\n\t\t\t\t\t */\n\t\t\t\t\tif ( input.errored ) throw input.errored\n\t\t\t\t\t\n\t\t\t\t\tconst KeyIV = (\n\t\t\t\t\t\tCipher.decrypt( encryptedKeyIV, secret, { algorithm, salt, iv, authTag } )\n\t\t\t\t\t)\n\n\t\t\t\t\tconst Key\t\t= KeyIV.subarray( 0, length )\n\t\t\t\t\tconst IV\t\t= KeyIV.subarray( length )\n\t\t\t\t\tconst decipher\t= crypto.createDecipheriv( algorithm, Key, IV )\n\t\n\t\t\t\t\tconst decrypt = () => (\n\t\t\t\t\t\tCipher.decipherStream(\n\t\t\t\t\t\t\t{ decipher, input, output }\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\n\t\t\t\t\treturn { decipher, decrypt }\n\t\t\t\t} )\n\t\t)\n\t}\n\n\n\t/**\n\t * Encrypt a `Readable` to a `Writable` Stream with hybird Encryption.\n\t *\n\t * The `Readable` Stream could be 'in-memory buffer' or 'file' based.\n\t *\n\t * @param\tsecret\t\tThe secret key used to encrypt the stream.\n\t * @param\tpublicKey\tThe RSA public key used to encrypt the symmetric key.\n\t * @param\toptions\t\tOptions for the stream encryption.\n\t * @returns An object containing:\n\t * \t- a new instance of `crypto.Cipher` allowing you to add listeners to the `cipher` encryption process.\n\t * \t- the actual `encrypt` callback that must be called and awaited in order to start the encryption process.\n\t */\n\tstatic hybridEncrypt(\n\t\tsecret\t\t: CoerceToUint8ArrayInput,\n\t\tpublicKey\t: crypto.RsaPublicKey | crypto.RsaPrivateKey | crypto.KeyLike,\n\t\toptions\t\t: Cph.Stream.Hybrid.EncryptOptions,\n\t): Cph.Stream.Hybrid.EncryptReturnType\n\t{\n\t\toptions.algorithm ||= Cipher.DEFAULT_ALGORITHM.stream\n\n\t\tconst {\n\t\t\tKey, IV,\n\t\t\toptions: { algorithm, input, output },\n\t\t} = Cipher.newKeyIV<Cph.Stream.Hybrid.EncryptResolvedOptions>( secret, options )\n\n\t\tconst encryptedKey = (\n\t\t\tcrypto.publicEncrypt( publicKey, Buffer.concat( [ Key, IV ] ) )\n\t\t)\n\n\t\tconst cipher = crypto.createCipheriv( algorithm, Key, IV )\n\t\tconst encrypt = () => (\n\t\t\tCipher.stream( {\n\t\t\t\tcipher, input, output, encryptedKey\n\t\t\t} )\n\t\t)\n\n\t\treturn { cipher, encrypt }\n\t}\n\n\n\t/**\n\t * Decrypt a `Readable` to a `Writable` Stream with hybrid Decryption.\n\t * \n\t * The `Readable` Stream could be 'in-memory buffer' or 'file' based.\n\t *\n\t * @param\tprivateKey\tThe RSA private key used to decrypt the symmetric key.\n\t * @param\toptions\t\tOptions for the stream decryption.\n\t * @returns A new Promise that resolves when Key IV extraction completes returning an object containing:\n\t * \t- a new instance of `crypto.Decipher` allowing you to add listeners to the `decipher` decryption process.\n\t * \t- the actual `decrypt` callback that must be called and awaited in order to start the decryption process.\n\t */\n\tstatic hybridDecrypt(\n\t\tprivateKey\t: crypto.RsaPrivateKey | crypto.KeyLike,\n\t\toptions\t\t: Cph.Stream.Hybrid.DecryptOptions,\n\t): Promise<Cph.Stream.Hybrid.DecryptReturnType>\n\t{\n\t\toptions.algorithm ||= Cipher.DEFAULT_ALGORITHM.stream\n\n\t\tconst {\n\t\t\tinput, output, algorithm, length, rsaKeyLength,\n\t\t} = Cipher.resolveOptions<Cph.Stream.Hybrid.DecryptResolvedOptions>( options )\n\n\t\treturn (\n\t\t\tCipher.extractKeyIV( input, rsaKeyLength )\n\t\t\t\t.then( ( [ encryptedKeyIV, input ] ) => {\n\t\t\t\t\tconst KeyIV\t\t= crypto.privateDecrypt( privateKey, encryptedKeyIV )\n\t\t\t\t\tconst Key\t\t= KeyIV.subarray( 0, length )\n\t\t\t\t\tconst IV\t\t= KeyIV.subarray( length )\n\t\t\t\t\tconst decipher\t= crypto.createDecipheriv( algorithm, Key, IV )\n\t\n\t\t\t\t\tconst decrypt = () => (\n\t\t\t\t\t\tCipher.decipherStream(\n\t\t\t\t\t\t\t{ decipher, input, output }\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\n\t\t\t\t\treturn { decipher, decrypt }\n\t\t\t\t} )\n\t\t)\n\t}\n\n\n\t/**\n\t * Handle pipe flow to encrypt a Stream.\n\t * \n\t * @param\toptions Required parameters.\n\t * @returns A new Promise that resolves `void` once stream is completed.\n\t */\n\tprivate static stream( options: StreamEncryptOptions )\n\t{\n\t\tconst {\n\t\t\tcipher, encryptedKey,\n\t\t\tinput, output\n\t\t} = options\n\n\t\treturn (\n\t\t\tnew Promise<void>( ( resolve, reject ) => {\n\t\t\t\tcipher.on( 'error', reject )\n\t\t\t\tinput.on( 'error', reject )\n\t\t\t\toutput.on( 'error', reject )\n\t\t\t\toutput.on( 'finish', resolve )\n\t\t\n\t\t\t\toutput.write( encryptedKey )\n\t\t\t\tinput.pipe( cipher ).pipe( output )\n\t\t\t} )\n\t\t)\n\t}\n\n\n\t/**\n\t * Handle pipe flow to decrypt a Stream.\n\t * \n\t * @param\toptions Required parameters.\n\t * @returns A new Promise that resolves `void` once stream is completed.\n\t */\n\tprivate static decipherStream( options: StreamDecryptOptions )\n\t{\n\t\tconst {\n\t\t\tdecipher, input, output,\n\t\t} = options\n\n\t\treturn (\n\t\t\tnew Promise<void>( ( resolve, reject ) => {\n\t\t\t\tdecipher.on( 'error', reject )\n\t\t\t\tinput.on( 'error', reject )\n\t\t\t\toutput.on( 'error', reject )\n\t\t\t\toutput.on( 'finish', resolve )\n\n\t\t\t\tinput.pipe( decipher ).pipe( output )\n\t\t\t} )\n\t\t)\n\t}\n\n\n\t/**\n\t * Extract the Cipher Encrypted Symmetric Key and Initialization Vector from an encrypted `Readable` Stream.\n\t *\n\t * @param\tinput\t\tThe `Readable` Stream.\n\t * @param\tkeyLength\tThe encrypted key length in bytes. This is used to properly extract the encrypted Cipher Key and Initialization Vector.\n\t * @returns\tA new Promise that resolve a tuple containing the Cipher Encrypted Symmetric Key and Initialization Vector once fulfilled.\n\t */\n\tprivate static extractKeyIV(\n\t\tinput\t\t: Readable,\n\t\tkeyLength\t: number,\n\t)\n\t{\n\t\treturn (\n\t\t\tnew Promise<[ KeyIV: Buffer, input: Transform ]>( ( resolve, reject ) => {\n\t\t\t\tlet KeyIV\t\t= Buffer.alloc( 0 )\n\t\t\t\tlet bytesRead\t= 0\n\t\t\t\tlet resolved\t= false\n\n\t\t\t\tconst transform = new Transform( {\n\t\t\t\t\tasync transform( chunk: Buffer, encoding, callback )\n\t\t\t\t\t{\n\n\t\t\t\t\t\tif ( KeyIV.length < keyLength ) {\n\t\t\t\t\t\t\tKeyIV = Buffer.concat( [ KeyIV, chunk ] )\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbytesRead += chunk.length\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * `KeyIV` length may exceed the `keyLength`.\n\t\t\t\t\t\t * This may occurs when the received chunk length is not a multiple of the `keyLength`.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * In that case the chunk will contain mixed content:\n\t\t\t\t\t\t * - end of the `KeyIV`.\n\t\t\t\t\t\t * - begin of the actual encrypted data.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * For a proper data handling we need to:\n\t\t\t\t\t\t * - cut off the `KeyIV` to `keyLength` bytes.\n\t\t\t\t\t\t * - recover and push the byte loss to the next piped destination.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif ( KeyIV.length > keyLength ) {\n\t\t\t\t\t\t\tconst bytesLoss\t= Math.max( 0, KeyIV.length - keyLength )\n\t\t\t\t\t\t\tKeyIV\t\t\t= KeyIV.subarray( 0, keyLength )\n\t\t\t\t\t\t\tconst subchunk\t= chunk.subarray( bytesLoss * -1 )\n\n\t\t\t\t\t\t\tif ( ! resolved ) {\n\t\t\t\t\t\t\t\tresolve( [ KeyIV, this ] )\n\t\t\t\t\t\t\t\tresolved = true\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t/**\n\t\t\t\t\t\t\t * Push to the next piped destination.\n\t\t\t\t\t\t\t */\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tthis.push( subchunk, encoding )\n\n\t\t\t\t\t\t\treturn callback()\n\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * `KeyIV` has been read.\n\t\t\t\t\t\t * The Received chunk can now be pushed to the next piped destination.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif ( bytesRead > keyLength ) {\n\t\t\t\t\t\t\tif ( ! resolved ) {\n\t\t\t\t\t\t\t\tresolve( [ KeyIV, this ] )\n\t\t\t\t\t\t\t\tresolved = true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t/**\n\t\t\t\t\t\t\t * Push to the next piped destination.\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\tthis.push( chunk, encoding )\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn callback()\n\t\t\t\t\t},\n\t\t\t\t\tfinal( callback )\n\t\t\t\t\t{\n\t\t\t\t\t\tif ( KeyIV.length < keyLength ) {\n\t\t\t\t\t\t\treturn callback(\n\t\t\t\t\t\t\t\tnew Error( 'The extracted KeyIV length is less than the expected length.' )\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn callback()\n\t\t\t\t\t},\n\t\t\t\t} )\n\n\t\t\t\ttransform.on( 'error', reject )\n\t\t\t\tinput.on( 'error', error => {\n\t\t\t\t\ttransform.destroy( error )\n\t\t\t\t\treject( error )\n\t\t\t\t} )\n\t\t\t\tinput.pipe( transform )\n\t\t\t} )\n\t\t)\n\t}\n\n\n\t/**\n\t * Generates a `Scrypt` Symmetric Key and the Initialization Vector with the given options.\n\t * \n\t * @param\tsecret\tThe secret key.\n\t * @param\toptions\t( Optional ) Additional options.\n\t * \n\t * @returns An object with the generated `Key`, `IV`, `salt` and resolved `options`. \n\t */\n\tstatic newKeyIV<T extends Cph.ResolvedOptions = Cph.ResolvedOptions>(\n\t\tsecret\t: CoerceToUint8ArrayInput,\n\t\toptions\t: Cph.Options = {},\n\t)\n\t{\n\t\tconst _secret\t= coerceToUint8Array( secret )\n\t\tconst _options\t= Cipher.resolveOptions<T>( options )\n\t\tconst salt\t\t= crypto.randomBytes( _options.salt )\n\t\tconst Key\t\t= crypto.scryptSync( _secret, salt, _options.length )\n\t\tconst IV\t\t= crypto.randomBytes( _options.iv )\n\t\tconst AAD\t\t= _options.aad || crypto.scryptSync( Key, salt, _options.aadLength )\n\n\t\treturn { options: _options, Key, IV, AAD, salt }\n\t}\n\n\n\t/**\n\t * Resolves the given `options` with `Cipher` defaults and constraints.\n\t * \n\t * @param options ( Optional ) Additional options.\n\t * @returns The given `options` with `Cipher` defaults and constraints.\n\t */\n\tstatic resolveOptions<\n\t\tT extends Cph.ResolvedOptions = Cph.ResolvedOptions\n\t>( options: Cph.Options = {} ): T\n\t{\n\t\tconst _options = { ...options } as T\n\n\t\tif ( _options.aad ) {\n\t\t\t_options.aad = coerceToUint8Array( _options.aad )\n\t\t}\n\n\t\t_options.salt\t\t||= Cipher.SALT_LENGTH.default\n\t\t_options.authTag\t||= Cipher.AUTH_TAG_LENGTH.default\n\t\t_options.aadLength\t= _options.aad?.length || _options.aadLength || Cipher.AAD_LENGTH.default\n\t\t_options.salt\t\t= Math.min( Math.max( _options.salt, Cipher.SALT_LENGTH.min ), Cipher.SALT_LENGTH.max )\n\t\t_options.authTag\t= Math.min( Math.max( _options.authTag, Cipher.AUTH_TAG_LENGTH.min ), Cipher.AUTH_TAG_LENGTH.max )\n\t\tif ( ! _options.aad ) {\n\t\t\t_options.aadLength\t= Math.min( Math.max( _options.aadLength, Cipher.AAD_LENGTH.min ), Cipher.AAD_LENGTH.max )\n\t\t}\n\n\t\tconst { keyLength, algorithm } = Cipher.getKeyLength( options.algorithm )\n\n\t\t_options.algorithm\t= algorithm\n\t\t_options.length\t\t= keyLength\n\t\t_options.iv\t\t\t= Cipher.getIVLength( algorithm, options )\n\n\t\treturn _options\n\t}\n\n\n\t/**\n\t * Get the Initialization Vector length based on the given algorithm.\n\t * \n\t * @param\talgorithm The algorithm in use.\n\t * @param\toptions ( Optional ) Additional options. \n\t * @returns\tThe Initialization Vector length based on the given algorithm\n\t */\n\tprivate static getIVLength(\n\t\talgorithm\t: Cph.Options[ 'algorithm' ] = Cipher.DEFAULT_ALGORITHM.buffer,\n\t\toptions\t\t: Cph.Options = {},\n\t)\n\t{\n\t\tswitch ( algorithm ) {\n\t\t\tcase 'aes-128-ccm':\n\t\t\tcase 'aes-128-ocb':\n\t\t\tcase 'aes-192-ccm':\n\t\t\tcase 'aes-192-ocb':\n\t\t\tcase 'aes-256-ccm':\n\t\t\tcase 'aes-256-ocb':\n\t\t\t\treturn 8\n\t\t\tcase 'chacha20-poly1305':\n\t\t\t\treturn 12\n\t\t\tdefault:\n\t\t\t\treturn (\n\t\t\t\t\tMath.min(\n\t\t\t\t\t\tMath.max(\n\t\t\t\t\t\t\toptions.iv || Cipher.IV_LENGTH.default,\n\t\t\t\t\t\t\tCipher.IV_LENGTH.min\n\t\t\t\t\t\t), Cipher.IV_LENGTH.max\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t}\n\t}\n\n\n\t/**\n\t * Ensure correct key length based on the given algorithm.\n\t *\n\t * @param\talgorithm The AES algorithm name.\n\t * @returns\tAn object with validated `algorithm` and `keyLength`.\n\t */\n\tprivate static getKeyLength(\n\t\talgorithm: Cph.Options[ 'algorithm' ] = Cipher.DEFAULT_ALGORITHM.buffer\n\t)\n\t{\n\t\tswitch ( algorithm ) {\n\t\t\tcase 'chacha20-poly1305':\n\t\t\t\treturn {\n\t\t\t\t\talgorithm: algorithm,\n\t\t\t\t\tkeyLength: 256 / 8,\n\t\t\t\t} as const\n\t\t\tcase 'aes-128-cbc':\n\t\t\tcase 'aes-128-ccm':\n\t\t\tcase 'aes-128-gcm':\n\t\t\tcase 'aes-128-ocb':\n\t\t\t\treturn {\n\t\t\t\t\talgorithm: algorithm,\n\t\t\t\t\tkeyLength: 128 / 8, // AES-128 needs a 128 bit (16 bytes)\n\t\t\t\t} as const\n\t\t\tcase 'aes-192-cbc':\n\t\t\tcase 'aes-192-ccm':\n\t\t\tcase 'aes-192-gcm':\n\t\t\tcase 'aes-192-ocb':\n\t\t\t\treturn {\n\t\t\t\t\talgorithm: algorithm,\n\t\t\t\t\tkeyLength: 192 / 8, // AES-192 needs a 192 bit (24 bytes)\n\t\t\t\t} as const\n\t\t\tcase 'aes-256-cbc':\n\t\t\tcase 'aes-256-ccm':\n\t\t\tcase 'aes-256-gcm':\n\t\t\tcase 'aes-256-ocb':\n\t\t\tdefault:\n\t\t\t\treturn {\n\t\t\t\t\talgorithm: algorithm,\n\t\t\t\t\tkeyLength: 256 / 8, // AES-256 needs a 256 bit (32 bytes)\n\t\t\t\t} as const\n\t\t}\n\t}\n\n\n\t/**\n\t * Check if the given algorithm is a Cipher AES-GCM algorithm.\n\t * \n\t * @param algorithm The AES Algorithm to check.\n\t * @returns `true` if the given algorithm is a Cipher AES-GCM algorithm. `false` otherwise.\n\t */\n\tstatic isGCM( algorithm: Cph.AesAlgorithm ): algorithm is crypto.CipherGCMTypes\n\t{\n\t\treturn (\n\t\t\talgorithm === 'aes-128-gcm' ||\n\t\t\talgorithm === 'aes-192-gcm' ||\n\t\t\talgorithm === 'aes-256-gcm'\n\t\t)\n\t}\n\n\n\t/**\n\t * Check if the given algorithm is a Cipher AES-CCM algorithm.\n\t * \n\t * @param algorithm The AES Algorithm to check.\n\t * @returns `true` if the given algorithm is a Cipher AES-CCM algorithm. `false` otherwise.\n\t */\n\tstatic isCCM( algorithm: Cph.AesAlgorithm ): algorithm is crypto.CipherCCMTypes\n\t{\n\t\treturn (\n\t\t\talgorithm === 'aes-128-ccm' ||\n\t\t\talgorithm === 'aes-192-ccm' ||\n\t\t\talgorithm === 'aes-256-ccm' ||\n\t\t\talgorithm === 'chacha20-poly1305'\n\t\t)\n\t}\n\n\n\t/**\n\t * Check if the given algorithm is a Cipher AES-OCB algorithm.\n\t * \n\t * @param algorithm The AES Algorithm to check.\n\t * @returns `true` if the given algorithm is a Cipher AES-OCB algorithm. `false` otherwise.\n\t */\n\tstatic isOCB( algorithm: Cph.AesAlgorithm ): algorithm is crypto.CipherOCBTypes\n\t{\n\t\treturn (\n\t\t\talgorithm === 'aes-128-ocb' ||\n\t\t\talgorithm === 'aes-192-ocb' ||\n\t\t\talgorithm === 'aes-256-ocb'\n\t\t)\n\t}\n\n\n\t/**\n\t * Check if the given algorithm is a Cipher AES-CBC algorithm.\n\t * \n\t * @param algorithm The AES Algorithm to check.\n\t * @returns `true` if the given algorithm is a Cipher AES-CBC algorithm. `false` otherwise.\n\t */\n\tstatic isCBC( algorithm: Cph.AesAlgorithm ): algorithm is Cph.CBCTypes\n\t{\n\t\treturn (\n\t\t\talgorithm === 'aes-128-cbc' ||\n\t\t\talgorithm === 'aes-192-cbc' ||\n\t\t\talgorithm === 'aes-256-cbc'\n\t\t)\n\t}\n}"]}
|
package/dist/types.d.mts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { CoerceToUint8ArrayInput } from '@alessiofrittoli/crypto-buffer';
|
|
2
1
|
import crypto from 'crypto';
|
|
3
2
|
import { Readable, Writable } from 'stream';
|
|
3
|
+
import { CoerceToUint8ArrayInput } from '@alessiofrittoli/crypto-buffer';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Cipher types.
|
|
7
|
+
*/
|
|
5
8
|
declare namespace Cph {
|
|
6
9
|
/** Cipher CBC algorithm types. */
|
|
7
10
|
type CBCTypes = 'aes-128-cbc' | 'aes-192-cbc' | 'aes-256-cbc';
|
|
8
11
|
/** Cipher supported algorithm types. */
|
|
9
|
-
type AesAlgorithm = (crypto.CipherCCMTypes | crypto.CipherGCMTypes | crypto.CipherOCBTypes | Cph.CBCTypes);
|
|
12
|
+
type AesAlgorithm = (crypto.CipherCCMTypes | crypto.CipherGCMTypes | crypto.CipherOCBTypes | Cph.CBCTypes | crypto.CipherChaCha20Poly1305Types);
|
|
10
13
|
/**
|
|
11
14
|
* Common Cipher options.
|
|
12
15
|
* @template T The AES algorithm type.
|
|
@@ -48,6 +51,15 @@ declare namespace Cph {
|
|
|
48
51
|
* Resolved Stream Encrypt options (symmetric and hybrid).
|
|
49
52
|
*/
|
|
50
53
|
type EncryptResolvedOptions = (Cph.ResolvedOptions & Required<Cph.Stream.Symmetric.EncryptOptions>);
|
|
54
|
+
/**
|
|
55
|
+
* Returnign object from `Cipher.encryptStream()` method.
|
|
56
|
+
*/
|
|
57
|
+
interface EncryptReturnType {
|
|
58
|
+
/** The `crypto.Cipher` instance. */
|
|
59
|
+
cipher: crypto.Cipher;
|
|
60
|
+
/** The actual `encrypt` callback that must be called and awaited in order to start the encryption process. */
|
|
61
|
+
encrypt: () => Promise<void>;
|
|
62
|
+
}
|
|
51
63
|
/**
|
|
52
64
|
* Options for decrypting a stream (symmetric).
|
|
53
65
|
*/
|
|
@@ -61,6 +73,12 @@ declare namespace Cph {
|
|
|
61
73
|
* Resolved Stream Decrypt options (symmetric).
|
|
62
74
|
*/
|
|
63
75
|
type DecryptResolvedOptions = (Cph.ResolvedOptions & Required<Cph.Stream.Symmetric.DecryptOptions>);
|
|
76
|
+
interface DecryptReturnType {
|
|
77
|
+
/** The `crypto.Decipher` instance. */
|
|
78
|
+
decipher: crypto.Decipher;
|
|
79
|
+
/** The actual `decrypt` callback that must be called and awaited in order to start the decryption process. */
|
|
80
|
+
decrypt: () => Promise<void>;
|
|
81
|
+
}
|
|
64
82
|
}
|
|
65
83
|
namespace Hybrid {
|
|
66
84
|
/**
|
|
@@ -82,6 +100,14 @@ declare namespace Cph {
|
|
|
82
100
|
* Resolved Stream Decrypt options.
|
|
83
101
|
*/
|
|
84
102
|
type DecryptResolvedOptions = (Cph.ResolvedOptions & Required<Cph.Stream.Hybrid.DecryptOptions>);
|
|
103
|
+
/**
|
|
104
|
+
* Alias for {@link Cph.Stream.Symmetric.EncryptReturnType}
|
|
105
|
+
*/
|
|
106
|
+
type EncryptReturnType = Cph.Stream.Symmetric.EncryptReturnType;
|
|
107
|
+
/**
|
|
108
|
+
* Alias for {@link Cph.Stream.Symmetric.DecryptReturnType}
|
|
109
|
+
*/
|
|
110
|
+
type DecryptReturnType = Cph.Stream.Symmetric.DecryptReturnType;
|
|
85
111
|
}
|
|
86
112
|
}
|
|
87
113
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { CoerceToUint8ArrayInput } from '@alessiofrittoli/crypto-buffer';
|
|
2
1
|
import crypto from 'crypto';
|
|
3
2
|
import { Readable, Writable } from 'stream';
|
|
3
|
+
import { CoerceToUint8ArrayInput } from '@alessiofrittoli/crypto-buffer';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Cipher types.
|
|
7
|
+
*/
|
|
5
8
|
declare namespace Cph {
|
|
6
9
|
/** Cipher CBC algorithm types. */
|
|
7
10
|
type CBCTypes = 'aes-128-cbc' | 'aes-192-cbc' | 'aes-256-cbc';
|
|
8
11
|
/** Cipher supported algorithm types. */
|
|
9
|
-
type AesAlgorithm = (crypto.CipherCCMTypes | crypto.CipherGCMTypes | crypto.CipherOCBTypes | Cph.CBCTypes);
|
|
12
|
+
type AesAlgorithm = (crypto.CipherCCMTypes | crypto.CipherGCMTypes | crypto.CipherOCBTypes | Cph.CBCTypes | crypto.CipherChaCha20Poly1305Types);
|
|
10
13
|
/**
|
|
11
14
|
* Common Cipher options.
|
|
12
15
|
* @template T The AES algorithm type.
|
|
@@ -48,6 +51,15 @@ declare namespace Cph {
|
|
|
48
51
|
* Resolved Stream Encrypt options (symmetric and hybrid).
|
|
49
52
|
*/
|
|
50
53
|
type EncryptResolvedOptions = (Cph.ResolvedOptions & Required<Cph.Stream.Symmetric.EncryptOptions>);
|
|
54
|
+
/**
|
|
55
|
+
* Returnign object from `Cipher.encryptStream()` method.
|
|
56
|
+
*/
|
|
57
|
+
interface EncryptReturnType {
|
|
58
|
+
/** The `crypto.Cipher` instance. */
|
|
59
|
+
cipher: crypto.Cipher;
|
|
60
|
+
/** The actual `encrypt` callback that must be called and awaited in order to start the encryption process. */
|
|
61
|
+
encrypt: () => Promise<void>;
|
|
62
|
+
}
|
|
51
63
|
/**
|
|
52
64
|
* Options for decrypting a stream (symmetric).
|
|
53
65
|
*/
|
|
@@ -61,6 +73,12 @@ declare namespace Cph {
|
|
|
61
73
|
* Resolved Stream Decrypt options (symmetric).
|
|
62
74
|
*/
|
|
63
75
|
type DecryptResolvedOptions = (Cph.ResolvedOptions & Required<Cph.Stream.Symmetric.DecryptOptions>);
|
|
76
|
+
interface DecryptReturnType {
|
|
77
|
+
/** The `crypto.Decipher` instance. */
|
|
78
|
+
decipher: crypto.Decipher;
|
|
79
|
+
/** The actual `decrypt` callback that must be called and awaited in order to start the decryption process. */
|
|
80
|
+
decrypt: () => Promise<void>;
|
|
81
|
+
}
|
|
64
82
|
}
|
|
65
83
|
namespace Hybrid {
|
|
66
84
|
/**
|
|
@@ -82,6 +100,14 @@ declare namespace Cph {
|
|
|
82
100
|
* Resolved Stream Decrypt options.
|
|
83
101
|
*/
|
|
84
102
|
type DecryptResolvedOptions = (Cph.ResolvedOptions & Required<Cph.Stream.Hybrid.DecryptOptions>);
|
|
103
|
+
/**
|
|
104
|
+
* Alias for {@link Cph.Stream.Symmetric.EncryptReturnType}
|
|
105
|
+
*/
|
|
106
|
+
type EncryptReturnType = Cph.Stream.Symmetric.EncryptReturnType;
|
|
107
|
+
/**
|
|
108
|
+
* Alias for {@link Cph.Stream.Symmetric.DecryptReturnType}
|
|
109
|
+
*/
|
|
110
|
+
type DecryptReturnType = Cph.Stream.Symmetric.DecryptReturnType;
|
|
85
111
|
}
|
|
86
112
|
}
|
|
87
113
|
}
|
package/dist/types.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
'use strict'
|
|
1
|
+
'use strict';//# sourceMappingURL=types.js.map
|
|
2
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"types.js"}
|
package/dist/types.mjs
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"types.mjs"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alessiofrittoli/crypto-cipher",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Node.js Cipher cryptograph utility library",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Alessio Frittoli",
|
|
@@ -8,6 +8,12 @@
|
|
|
8
8
|
"url": "https://alessiofrittoli.it"
|
|
9
9
|
},
|
|
10
10
|
"license": "MIT",
|
|
11
|
+
"funding": [
|
|
12
|
+
{
|
|
13
|
+
"type": "github",
|
|
14
|
+
"url": "https://github.com/sponsors/alessiofrittoli"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
11
17
|
"keywords": [
|
|
12
18
|
"nodejs-crypto",
|
|
13
19
|
"cryptography",
|
|
@@ -46,19 +52,29 @@
|
|
|
46
52
|
},
|
|
47
53
|
"sideEffects": false,
|
|
48
54
|
"scripts": {
|
|
55
|
+
"//1a": "*********************************************************************",
|
|
56
|
+
"//1b": "*********************** BUILD - LINT - RELEASE **********************",
|
|
57
|
+
"//1c": "*********************************************************************",
|
|
49
58
|
"build": "pnpm lint && pnpm test:ci && tsup",
|
|
50
59
|
"build:watch": "tsup --watch",
|
|
51
60
|
"lint": "eslint",
|
|
52
61
|
"release": "node scripts/publish.js --verbose --npm",
|
|
53
|
-
"
|
|
62
|
+
"//2a": "*********************************************************************",
|
|
63
|
+
"//2b": "***************************** UNIT TESTS ****************************",
|
|
64
|
+
"//2c": "*********************************************************************",
|
|
65
|
+
"test": "jest --verbose",
|
|
54
66
|
"test:watch": "jest --watchAll --verbose",
|
|
55
67
|
"test:ci": "jest --ci --verbose",
|
|
68
|
+
"//3a": "*********************************************************************",
|
|
69
|
+
"//3b": "************************ UNIT TESTS COVERAGE ************************",
|
|
70
|
+
"//3c": "*********************************************************************",
|
|
56
71
|
"test:coverage": "pnpm test:watch --coverage",
|
|
57
72
|
"test:ci:coverage": "pnpm test:ci --coverage",
|
|
58
73
|
"test:serve-coverage": "http-server ./coverage/lcov-report --gzip true -p 0 -o --silent",
|
|
59
74
|
"test:coverage:serve": "concurrently --prefix none --kill-others \"pnpm test:coverage\" \"pnpm test:serve-coverage\"",
|
|
60
|
-
"
|
|
61
|
-
"
|
|
75
|
+
"//4a": "*********************************************************************",
|
|
76
|
+
"//4b": "************************ TARGETED UNIT TESTS ************************",
|
|
77
|
+
"//4c": "*********************************************************************",
|
|
62
78
|
"test:buffer-in-memory": "pnpm test:watch buffer-in-memory.test.ts",
|
|
63
79
|
"test:file-symmetric": "pnpm test:watch file-symmetric.test.ts",
|
|
64
80
|
"test:file-hybrid": "pnpm test:watch file-hybrid.test.ts",
|
|
@@ -67,25 +83,29 @@
|
|
|
67
83
|
"test:misc": "pnpm test:watch misc.test.ts"
|
|
68
84
|
},
|
|
69
85
|
"devDependencies": {
|
|
70
|
-
"@alessiofrittoli/node-scripts": "^2.
|
|
71
|
-
"@eslint/js": "^9.
|
|
86
|
+
"@alessiofrittoli/node-scripts": "^2.4.0",
|
|
87
|
+
"@eslint/js": "^9.23.0",
|
|
72
88
|
"@jest/globals": "^29.7.0",
|
|
73
89
|
"@types/jest": "^29.5.14",
|
|
74
|
-
"@types/node": "^22.
|
|
90
|
+
"@types/node": "^22.13.11",
|
|
75
91
|
"concurrently": "^9.1.2",
|
|
76
92
|
"dotenv": "^16.4.7",
|
|
77
|
-
"eslint": "^9.
|
|
78
|
-
"globals": "^
|
|
93
|
+
"eslint": "^9.23.0",
|
|
94
|
+
"globals": "^16.0.0",
|
|
79
95
|
"http-server": "^14.1.1",
|
|
80
96
|
"jest": "^29.7.0",
|
|
81
|
-
"jest
|
|
82
|
-
"ts-jest": "^29.2.5",
|
|
97
|
+
"ts-jest": "^29.2.6",
|
|
83
98
|
"ts-node": "^10.9.2",
|
|
84
|
-
"tsup": "^8.
|
|
85
|
-
"typescript": "^5.
|
|
86
|
-
"typescript-eslint": "^8.
|
|
99
|
+
"tsup": "^8.4.0",
|
|
100
|
+
"typescript": "^5.8.2",
|
|
101
|
+
"typescript-eslint": "^8.27.0"
|
|
87
102
|
},
|
|
88
103
|
"dependencies": {
|
|
89
|
-
"@alessiofrittoli/crypto-buffer": "^3.
|
|
104
|
+
"@alessiofrittoli/crypto-buffer": "^3.5.0"
|
|
105
|
+
},
|
|
106
|
+
"pnpm": {
|
|
107
|
+
"onlyBuiltDependencies": [
|
|
108
|
+
"esbuild"
|
|
109
|
+
]
|
|
90
110
|
}
|
|
91
111
|
}
|