@alessiofrittoli/crypto-cipher 2.2.0 → 3.0.0-alpha.2

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/dist/index.d.ts CHANGED
@@ -1,214 +1,4 @@
1
- import crypto from 'crypto';
2
- import { CoerceToUint8ArrayInput } from '@alessiofrittoli/crypto-buffer/coercion';
3
- import { Cph } from './types.js';
4
- import 'stream';
1
+ import 'crypto';
5
2
  import '@alessiofrittoli/crypto-buffer';
6
-
7
- /**
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.
9
- */
10
- declare class Cipher {
11
- /**
12
- * Cipher default `salt` lengths.
13
- */
14
- static readonly SALT_LENGTH: {
15
- readonly min: 16;
16
- readonly max: 64;
17
- readonly default: 32;
18
- };
19
- /**
20
- * Cipher default `IV` lengths.
21
- */
22
- static readonly IV_LENGTH: {
23
- readonly min: 8;
24
- readonly max: 32;
25
- readonly default: 16;
26
- };
27
- /**
28
- * Cipher default `Auth Tag` lengths.
29
- */
30
- static readonly AUTH_TAG_LENGTH: {
31
- readonly min: 4;
32
- readonly max: 16;
33
- readonly default: 16;
34
- };
35
- /**
36
- * Cipher default `Additional Authenticated Data` lengths.
37
- */
38
- static readonly AAD_LENGTH: {
39
- readonly min: 16;
40
- readonly max: 128;
41
- readonly default: 32;
42
- };
43
- /**
44
- * Default AES algorithms used based on functionality.
45
- */
46
- static readonly DEFAULT_ALGORITHM: {
47
- readonly buffer: "aes-256-gcm";
48
- readonly stream: "aes-256-cbc";
49
- };
50
- /**
51
- * Supported AES algorithms.
52
- */
53
- static readonly ALGORITHMS: Cph.AesAlgorithm[];
54
- /**
55
- * Encrypt in-memory data buffer.
56
- *
57
- * ⚠️ This is not suitable for large data. Use {@link Cipher.streamEncrypt()} or {@link Cipher.hybridEncrypt()} methods for large data encryption.
58
- *
59
- * @param data The data to encrypt.
60
- * @param secret The secret key used to encrypt the `data`.
61
- * @param options ( Optional ) Additional options.
62
- * @returns The encrypted result Buffer.
63
- */
64
- static encrypt(data: CoerceToUint8ArrayInput, secret: CoerceToUint8ArrayInput, options?: Cph.Options): Buffer;
65
- /**
66
- * Decrypt in-memory data buffer.
67
- *
68
- * ⚠️ This is not suitable for large data. Use {@link Cipher.streamDecrypt()} or {@link Cipher.hybridDecrypt()} methods for large data decryption.
69
- *
70
- * @param data The data to decrypt.
71
- * @param secret The secret key used to decrypt the `data`.
72
- * @param options ( Optional ) Additional options. Must be the same used while encrypting data.
73
- * @returns The decrypted data Buffer.
74
- */
75
- static decrypt(data: CoerceToUint8ArrayInput, secret: CoerceToUint8ArrayInput, options?: Cph.Options): Buffer;
76
- /**
77
- * Encrypt a `Readable` to a `Writable` Stream.
78
- *
79
- * The `Readable` Stream could be 'in-memory buffer' or 'file' based.
80
- *
81
- * @param secret The secret key used to encrypt the `data`.
82
- * @param options Additional options.
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.
86
- */
87
- static streamEncrypt(secret: CoerceToUint8ArrayInput, options: Cph.Stream.Symmetric.EncryptOptions): Cph.Stream.Symmetric.EncryptReturnType;
88
- /**
89
- * Decrypt a `Readable` to a `Writable` Stream.
90
- *
91
- * The `Readable` Stream could be 'in-memory buffer' or 'file' based.
92
- *
93
- * @param secret The secret key used to encrypt the `data`.
94
- * @param options Additional options.
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.
98
- */
99
- static streamDecrypt(secret: CoerceToUint8ArrayInput, options: Cph.Stream.Symmetric.DecryptOptions): Promise<Cph.Stream.Symmetric.DecryptReturnType>;
100
- /**
101
- * Encrypt a `Readable` to a `Writable` Stream with hybird Encryption.
102
- *
103
- * The `Readable` Stream could be 'in-memory buffer' or 'file' based.
104
- *
105
- * @param secret The secret key used to encrypt the stream.
106
- * @param publicKey The RSA public key used to encrypt the symmetric key.
107
- * @param options Options for the stream encryption.
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.
111
- */
112
- static hybridEncrypt(secret: CoerceToUint8ArrayInput, publicKey: crypto.RsaPublicKey | crypto.RsaPrivateKey | crypto.KeyLike, options: Cph.Stream.Hybrid.EncryptOptions): Cph.Stream.Hybrid.EncryptReturnType;
113
- /**
114
- * Decrypt a `Readable` to a `Writable` Stream with hybrid Decryption.
115
- *
116
- * The `Readable` Stream could be 'in-memory buffer' or 'file' based.
117
- *
118
- * @param privateKey The RSA private key used to decrypt the symmetric key.
119
- * @param options Options for the stream decryption.
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.
123
- */
124
- static hybridDecrypt(privateKey: crypto.RsaPrivateKey | crypto.KeyLike, options: Cph.Stream.Hybrid.DecryptOptions): Promise<Cph.Stream.Hybrid.DecryptReturnType>;
125
- /**
126
- * Handle pipe flow to encrypt a Stream.
127
- *
128
- * @param options Required parameters.
129
- * @returns A new Promise that resolves `void` once stream is completed.
130
- */
131
- private static stream;
132
- /**
133
- * Handle pipe flow to decrypt a Stream.
134
- *
135
- * @param options Required parameters.
136
- * @returns A new Promise that resolves `void` once stream is completed.
137
- */
138
- private static decipherStream;
139
- /**
140
- * Extract the Cipher Encrypted Symmetric Key and Initialization Vector from an encrypted `Readable` Stream.
141
- *
142
- * @param input The `Readable` Stream.
143
- * @param keyLength The encrypted key length in bytes. This is used to properly extract the encrypted Cipher Key and Initialization Vector.
144
- * @returns A new Promise that resolve a tuple containing the Cipher Encrypted Symmetric Key and Initialization Vector once fulfilled.
145
- */
146
- private static extractKeyIV;
147
- /**
148
- * Generates a `Scrypt` Symmetric Key and the Initialization Vector with the given options.
149
- *
150
- * @param secret The secret key.
151
- * @param options ( Optional ) Additional options.
152
- *
153
- * @returns An object with the generated `Key`, `IV`, `salt` and resolved `options`.
154
- */
155
- static newKeyIV<T extends Cph.ResolvedOptions = Cph.ResolvedOptions>(secret: CoerceToUint8ArrayInput, options?: Cph.Options): {
156
- options: T;
157
- Key: Buffer<ArrayBufferLike>;
158
- IV: Buffer<ArrayBufferLike>;
159
- AAD: Buffer<ArrayBufferLike> | Uint8Array<ArrayBufferLike>;
160
- salt: Buffer<ArrayBufferLike>;
161
- };
162
- /**
163
- * Resolves the given `options` with `Cipher` defaults and constraints.
164
- *
165
- * @param options ( Optional ) Additional options.
166
- * @returns The given `options` with `Cipher` defaults and constraints.
167
- */
168
- static resolveOptions<T extends Cph.ResolvedOptions = Cph.ResolvedOptions>(options?: Cph.Options): T;
169
- /**
170
- * Get the Initialization Vector length based on the given algorithm.
171
- *
172
- * @param algorithm The algorithm in use.
173
- * @param options ( Optional ) Additional options.
174
- * @returns The Initialization Vector length based on the given algorithm
175
- */
176
- private static getIVLength;
177
- /**
178
- * Ensure correct key length based on the given algorithm.
179
- *
180
- * @param algorithm The AES algorithm name.
181
- * @returns An object with validated `algorithm` and `keyLength`.
182
- */
183
- private static getKeyLength;
184
- /**
185
- * Check if the given algorithm is a Cipher AES-GCM algorithm.
186
- *
187
- * @param algorithm The AES Algorithm to check.
188
- * @returns `true` if the given algorithm is a Cipher AES-GCM algorithm. `false` otherwise.
189
- */
190
- static isGCM(algorithm: Cph.AesAlgorithm): algorithm is crypto.CipherGCMTypes;
191
- /**
192
- * Check if the given algorithm is a Cipher AES-CCM algorithm.
193
- *
194
- * @param algorithm The AES Algorithm to check.
195
- * @returns `true` if the given algorithm is a Cipher AES-CCM algorithm. `false` otherwise.
196
- */
197
- static isCCM(algorithm: Cph.AesAlgorithm): algorithm is crypto.CipherCCMTypes;
198
- /**
199
- * Check if the given algorithm is a Cipher AES-OCB algorithm.
200
- *
201
- * @param algorithm The AES Algorithm to check.
202
- * @returns `true` if the given algorithm is a Cipher AES-OCB algorithm. `false` otherwise.
203
- */
204
- static isOCB(algorithm: Cph.AesAlgorithm): algorithm is crypto.CipherOCBTypes;
205
- /**
206
- * Check if the given algorithm is a Cipher AES-CBC algorithm.
207
- *
208
- * @param algorithm The AES Algorithm to check.
209
- * @returns `true` if the given algorithm is a Cipher AES-CBC algorithm. `false` otherwise.
210
- */
211
- static isCBC(algorithm: Cph.AesAlgorithm): algorithm is Cph.CBCTypes;
212
- }
213
-
214
- export { Cipher };
3
+ export { a as Cipher } from './index-B9WIVWrs.js';
4
+ import 'stream';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _crypto = require('crypto'); var _crypto2 = _interopRequireDefault(_crypto);var _stream = require('stream');var _coercion = require('@alessiofrittoli/crypto-buffer/coercion');var t=class t{static encrypt(r,e,o={}){let a=_coercion.coerceToUint8Array.call(void 0, r),{salt:c,Key:s,IV:n,AAD:p,options:{algorithm:i,authTag:h}}=t.newKeyIV(e,o);if(t.isCBC(i)){let T=_crypto2.default.createCipheriv(i,s,n),d=Buffer.concat([T.update(a),T.final()]);return Buffer.concat([c,n,d])}let y=_crypto2.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.call(void 0, r),c=_coercion.coerceToUint8Array.call(void 0, 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=_crypto2.default.scryptSync(c,p,s.length);if(t.isCBC(n)){let f=_crypto2.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=_crypto2.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=_crypto2.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=_crypto2.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=_crypto2.default.publicEncrypt(e,Buffer.concat([a,c])),h=_crypto2.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=_crypto2.default.privateDecrypt(r,p),y=h.subarray(0,s),u=h.subarray(s),l=_crypto2.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=!1,p=new (0, _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=!0),this.push(l,h),y()}return s>e&&(n||(o([c,this]),n=!0),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.call(void 0, r),a=t.resolveOptions(e),c=_crypto2.default.randomBytes(a.salt),s=_crypto2.default.scryptSync(o,c,a.length),n=_crypto2.default.randomBytes(a.iv),p=a.aad||_crypto2.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.call(void 0, e.aad)),e.salt||(e.salt=t.SALT_LENGTH.default),e.authTag||(e.authTag=t.AUTH_TAG_LENGTH.default),e.aadLength=_optionalChain([e, 'access', _ => _.aad, 'optionalAccess', _2 => _2.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;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _crypto = require('crypto'); var _crypto2 = _interopRequireDefault(_crypto);var _utils = require('@alessiofrittoli/stream-reader/utils');var _mathutils = require('@alessiofrittoli/math-utils');var _cryptobuffer = require('@alessiofrittoli/crypto-buffer');var t=class t{static Encrypt(a,e,s={}){let r=_cryptobuffer.coerceToUint8Array.call(void 0, a),{salt:n,Key:o,IV:c,AAD:A,options:{algorithm:p,authTag:h}}=t.NewKeyIV({...s,secret:e});if(t.IsCBC(p)){let I=_crypto2.default.createCipheriv(p,o,c),u=Buffer.concat([I.update(r),I.final()]);return Buffer.concat([n,c,u])}let y=_crypto2.default.createCipheriv(p,o,c,{authTagLength:h});(t.IsCCM(p)||t.IsChacha20Poly(p))&&y.setAAD(A,{plaintextLength:r.length}),(t.IsGCM(p)||t.IsOCB(p))&&y.setAAD(A);let C=Buffer.concat([y.update(r),y.final()]),L=y.getAuthTag();return Buffer.concat([n,c,A,L,C])}static Decrypt(a,e,s={}){let r=_cryptobuffer.coerceToUint8Array.call(void 0, a),n=t.ResolveOptions(s),o=_cryptobuffer.coerceToUint8Array.call(void 0, e),{algorithm:c}=n,A=r.subarray(0,n.salt);r=r.subarray(n.salt);let p=r.subarray(0,n.iv);r=r.subarray(n.iv);let h=_crypto2.default.scryptSync(o,A,n.length);if(t.IsCBC(c)){let G=_crypto2.default.createDecipheriv(n.algorithm,h,p);return Buffer.concat([G.update(r),G.final()])}let y=n.aadLength,C=n.authTag,L=r.subarray(0,y);r=r.subarray(y);let I=r.subarray(0,C);r=r.subarray(C);let u=_crypto2.default.createDecipheriv(c,h,p,{authTagLength:C});return(t.IsCCM(c)||t.IsChacha20Poly(c))&&u.setAAD(L,{plaintextLength:r.length}),(t.IsGCM(c)||t.IsOCB(c))&&u.setAAD(L),u.setAuthTag(I),Buffer.concat([u.update(r),u.final()])}static HybridEncrypt(a,e,s){let r=_crypto2.default.randomBytes(32),n=_crypto2.default.publicEncrypt({key:e,padding:_crypto2.default.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:"sha256"},r);return Buffer.concat([_cryptobuffer.writeUint32BE.call(void 0, n.length),n,t.Encrypt(a,r,s)])}static HybridDecrypt(a,e,s){let r=Buffer.from(_cryptobuffer.coerceToUint8Array.call(void 0, a)),n=_cryptobuffer.readUint32BE.call(void 0, r.subarray(0,4)),o=r.subarray(4,4+n),c=r.subarray(4+n),{privateKey:A,passphrase:p}=t.GetPrivateKey(e),h=_crypto2.default.privateDecrypt({key:A,passphrase:p,padding:_crypto2.default.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:"sha256"},o);return t.Decrypt(c,h,s)}static DecryptKeyIV(a){let{privateKey:e,EncryptedKeyIV:s,keyLength:r}=a,{privateKey:n,passphrase:o}=t.GetPrivateKey(e),c=_crypto2.default.privateDecrypt({key:n,passphrase:o,padding:_crypto2.default.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:"sha256"},s),A=c.subarray(0,r),p=c.subarray(r);return{Key:A,IV:p}}static GetPrivateKey(a){let e=typeof a=="object"&&"key"in a?a.key:a,s=typeof a=="object"&&"passphrase"in a?a.passphrase:void 0;return{privateKey:e,passphrase:s}}static NewKeyIV(a={}){let{secret:e}=a,s=t.ResolveOptions(a),r=e?_cryptobuffer.coerceToUint8Array.call(void 0, e):_crypto2.default.randomBytes(s.length),n=_crypto2.default.randomBytes(s.salt),o=_crypto2.default.scryptSync(r,n,s.length),c=_crypto2.default.randomBytes(s.iv),A=s.aad||_crypto2.default.scryptSync(o,n,s.aadLength);return{options:s,Key:o,IV:c,AAD:A,salt:n}}static ResolveOptions(a={}){let e={...a};e.aad&&(e.aad=_cryptobuffer.coerceToUint8Array.call(void 0, e.aad)),e.salt||(e.salt=t.SALT_LENGTH.default),e.authTag||(e.authTag=t.AUTH_TAG_LENGTH.default),e.aadLength=_optionalChain([e, 'access', _ => _.aad, 'optionalAccess', _2 => _2.length])||e.aadLength||t.AAD_LENGTH.default,e.salt=_mathutils.clamp.call(void 0, e.salt,t.SALT_LENGTH.min,t.SALT_LENGTH.max),e.authTag=_mathutils.clamp.call(void 0, e.authTag,t.AUTH_TAG_LENGTH.min,t.AUTH_TAG_LENGTH.max),e.aad||(e.aadLength=_mathutils.clamp.call(void 0, e.aadLength,t.AAD_LENGTH.min,t.AAD_LENGTH.max));let{keyLength:s,algorithm:r}=t.GetKeyLength(a.algorithm);return e.algorithm=r,e.length=s,e.iv=t.GetIVLength(r,a),e}static GetIVLength(a=t.DEFAULT_ALGORITHM.buffer,e={}){switch(a){case t.ALGORITHM.AES_128_CCM:case t.ALGORITHM.AES_192_CCM:case t.ALGORITHM.AES_256_CCM:case t.ALGORITHM.AES_128_OCB:case t.ALGORITHM.AES_192_OCB:case t.ALGORITHM.AES_256_OCB:return 8;case t.ALGORITHM.CHACHA_20_POLY:return 12;default:return _mathutils.clamp.call(void 0, e.iv||t.IV_LENGTH.default,t.IV_LENGTH.min,t.IV_LENGTH.max)}}static GetKeyLength(a=t.DEFAULT_ALGORITHM.buffer){switch(a){case t.ALGORITHM.CHACHA_20_POLY:return{algorithm:a,keyLength:256/8};case t.ALGORITHM.AES_128_CBC:case t.ALGORITHM.AES_128_CCM:case t.ALGORITHM.AES_128_GCM:case t.ALGORITHM.AES_128_OCB:return{algorithm:a,keyLength:128/8};case t.ALGORITHM.AES_192_CBC:case t.ALGORITHM.AES_192_CCM:case t.ALGORITHM.AES_192_GCM:case t.ALGORITHM.AES_192_OCB:return{algorithm:a,keyLength:192/8};case t.ALGORITHM.AES_256_CBC:case t.ALGORITHM.AES_256_CCM:case t.ALGORITHM.AES_256_GCM:case t.ALGORITHM.AES_256_OCB:default:return{algorithm:a,keyLength:256/8}}}static IsGCM(a){return a===t.ALGORITHM.AES_128_GCM||a===t.ALGORITHM.AES_192_GCM||a===t.ALGORITHM.AES_256_GCM}static IsCCM(a){return a===t.ALGORITHM.AES_128_CCM||a===t.ALGORITHM.AES_192_CCM||a===t.ALGORITHM.AES_256_CCM}static IsChacha20Poly(a){return a===t.ALGORITHM.CHACHA_20_POLY}static IsOCB(a){return a===t.ALGORITHM.AES_128_OCB||a===t.ALGORITHM.AES_192_OCB||a===t.ALGORITHM.AES_256_OCB}static IsCBC(a){return a===t.ALGORITHM.AES_128_CBC||a===t.ALGORITHM.AES_192_CBC||a===t.ALGORITHM.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.ALGORITHM={AES_128_CBC:"aes-128-cbc",AES_192_CBC:"aes-192-cbc",AES_256_CBC:"aes-256-cbc",AES_128_CCM:"aes-128-ccm",AES_192_CCM:"aes-192-ccm",AES_256_CCM:"aes-256-ccm",AES_128_GCM:"aes-128-gcm",AES_192_GCM:"aes-192-gcm",AES_256_GCM:"aes-256-gcm",AES_128_OCB:"aes-128-ocb",AES_192_OCB:"aes-192-ocb",AES_256_OCB:"aes-256-ocb",CHACHA_20_POLY:"chacha20-poly1305"},t.DEFAULT_ALGORITHM={buffer:t.ALGORITHM.AES_256_GCM,stream:t.ALGORITHM.AES_256_CBC},t.ALGORITHMS=Object.values(t.ALGORITHM),t.stream={Encrypt(a,e){e.algorithm||(e.algorithm=t.DEFAULT_ALGORITHM.stream);let{Key:s,IV:r,salt:n,options:{input:o,output:c,algorithm:A}}=t.NewKeyIV({secret:a,...e}),p=_crypto2.default.createCipheriv(A,s,r);return c.write(Buffer.concat([n,r])),t.stream.Cipher({cipher:p,input:o,output:c})},async Decrypt(a,e){e.algorithm||(e.algorithm=t.DEFAULT_ALGORITHM.stream);let{input:s,output:r,algorithm:n,length:o,salt:c,iv:A}=t.ResolveOptions(e),[p,h]=await _utils.extractBytesFromReadable.call(void 0, s,c+A),y=p.subarray(0,c),C=p.subarray(c),L=_crypto2.default.scryptSync(_cryptobuffer.coerceToUint8Array.call(void 0, a),y,o),I=_crypto2.default.createDecipheriv(n,L,C);return t.stream.Decipher({decipher:I,input:h,output:r})},HybridEncrypt(a,e){e.algorithm||(e.algorithm=t.DEFAULT_ALGORITHM.stream);let{Key:s,IV:r,options:{algorithm:n,input:o,output:c}}=t.NewKeyIV(e),A=_crypto2.default.publicEncrypt({key:a,padding:_crypto2.default.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:"sha256"},Buffer.concat([s,r])),p=_crypto2.default.createCipheriv(n,s,r);return t.stream.Cipher({cipher:p,encryptedKey:A,input:o,output:c})},HybridDecrypt(a,e){let{input:s,output:r}=e,{keyLength:n,algorithm:o}=t.GetKeyLength(e.algorithm||t.DEFAULT_ALGORITHM.stream);return new Promise((c,A)=>(s.on("error",A),r.on("error",A),t._stream.ExtractKeyLength(s).then(t._stream.ExtractKeyIV).then(([p,h])=>({...t.DecryptKeyIV({privateKey:a,EncryptedKeyIV:p,keyLength:n}),input:h})).then(async({Key:p,IV:h,input:y})=>{y.on("error",A);let C=_crypto2.default.createDecipheriv(o,p,h);await t.stream.Decipher({decipher:C,input:y,output:r}),c()}).catch(A)))},Cipher(a){let{cipher:e,encryptedKey:s,input:r,output:n}=a;return new Promise((o,c)=>{e.on("error",c),r.on("error",c),n.on("error",c),n.on("finish",o),s&&(n.write(_cryptobuffer.writeUint32BE.call(void 0, s.length)),n.write(s)),r.pipe(e).pipe(n)})},Decipher(a){let{decipher:e,input:s,output:r}=a;return new Promise((n,o)=>{e.on("error",o),s.on("error",o),r.on("error",o),r.on("finish",n),s.pipe(e).pipe(r)})}},t._stream={ExtractKeyLength(a){return _utils.extractBytesFromReadable.call(void 0, a,4).then(([e,s])=>[_cryptobuffer.readUint32BE.call(void 0, e),s])},ExtractKeyIV([a,e]){return _utils.extractBytesFromReadable.call(void 0, e,a)}};var d=t;exports.Cipher = d;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import m from"crypto";import{Transform as C}from"stream";import{coerceToUint8Array as g}from"@alessiofrittoli/crypto-buffer/coercion";var t=class t{static encrypt(r,e,o={}){let a=g(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=g(r),c=g(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=!1,p=new C({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=!0),this.push(l,h),y()}return s>e&&(n||(o([c,this]),n=!0),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=g(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=g(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};
1
+ import i from"crypto";import{extractBytesFromReadable as E}from"@alessiofrittoli/stream-reader/utils";import{clamp as O}from"@alessiofrittoli/math-utils";import{coerceToUint8Array as T,readUint32BE as l,writeUint32BE as m}from"@alessiofrittoli/crypto-buffer";var t=class t{static Encrypt(a,e,s={}){let r=T(a),{salt:n,Key:o,IV:c,AAD:A,options:{algorithm:p,authTag:h}}=t.NewKeyIV({...s,secret:e});if(t.IsCBC(p)){let I=i.createCipheriv(p,o,c),u=Buffer.concat([I.update(r),I.final()]);return Buffer.concat([n,c,u])}let y=i.createCipheriv(p,o,c,{authTagLength:h});(t.IsCCM(p)||t.IsChacha20Poly(p))&&y.setAAD(A,{plaintextLength:r.length}),(t.IsGCM(p)||t.IsOCB(p))&&y.setAAD(A);let C=Buffer.concat([y.update(r),y.final()]),L=y.getAuthTag();return Buffer.concat([n,c,A,L,C])}static Decrypt(a,e,s={}){let r=T(a),n=t.ResolveOptions(s),o=T(e),{algorithm:c}=n,A=r.subarray(0,n.salt);r=r.subarray(n.salt);let p=r.subarray(0,n.iv);r=r.subarray(n.iv);let h=i.scryptSync(o,A,n.length);if(t.IsCBC(c)){let G=i.createDecipheriv(n.algorithm,h,p);return Buffer.concat([G.update(r),G.final()])}let y=n.aadLength,C=n.authTag,L=r.subarray(0,y);r=r.subarray(y);let I=r.subarray(0,C);r=r.subarray(C);let u=i.createDecipheriv(c,h,p,{authTagLength:C});return(t.IsCCM(c)||t.IsChacha20Poly(c))&&u.setAAD(L,{plaintextLength:r.length}),(t.IsGCM(c)||t.IsOCB(c))&&u.setAAD(L),u.setAuthTag(I),Buffer.concat([u.update(r),u.final()])}static HybridEncrypt(a,e,s){let r=i.randomBytes(32),n=i.publicEncrypt({key:e,padding:i.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:"sha256"},r);return Buffer.concat([m(n.length),n,t.Encrypt(a,r,s)])}static HybridDecrypt(a,e,s){let r=Buffer.from(T(a)),n=l(r.subarray(0,4)),o=r.subarray(4,4+n),c=r.subarray(4+n),{privateKey:A,passphrase:p}=t.GetPrivateKey(e),h=i.privateDecrypt({key:A,passphrase:p,padding:i.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:"sha256"},o);return t.Decrypt(c,h,s)}static DecryptKeyIV(a){let{privateKey:e,EncryptedKeyIV:s,keyLength:r}=a,{privateKey:n,passphrase:o}=t.GetPrivateKey(e),c=i.privateDecrypt({key:n,passphrase:o,padding:i.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:"sha256"},s),A=c.subarray(0,r),p=c.subarray(r);return{Key:A,IV:p}}static GetPrivateKey(a){let e=typeof a=="object"&&"key"in a?a.key:a,s=typeof a=="object"&&"passphrase"in a?a.passphrase:void 0;return{privateKey:e,passphrase:s}}static NewKeyIV(a={}){let{secret:e}=a,s=t.ResolveOptions(a),r=e?T(e):i.randomBytes(s.length),n=i.randomBytes(s.salt),o=i.scryptSync(r,n,s.length),c=i.randomBytes(s.iv),A=s.aad||i.scryptSync(o,n,s.aadLength);return{options:s,Key:o,IV:c,AAD:A,salt:n}}static ResolveOptions(a={}){let e={...a};e.aad&&(e.aad=T(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=O(e.salt,t.SALT_LENGTH.min,t.SALT_LENGTH.max),e.authTag=O(e.authTag,t.AUTH_TAG_LENGTH.min,t.AUTH_TAG_LENGTH.max),e.aad||(e.aadLength=O(e.aadLength,t.AAD_LENGTH.min,t.AAD_LENGTH.max));let{keyLength:s,algorithm:r}=t.GetKeyLength(a.algorithm);return e.algorithm=r,e.length=s,e.iv=t.GetIVLength(r,a),e}static GetIVLength(a=t.DEFAULT_ALGORITHM.buffer,e={}){switch(a){case t.ALGORITHM.AES_128_CCM:case t.ALGORITHM.AES_192_CCM:case t.ALGORITHM.AES_256_CCM:case t.ALGORITHM.AES_128_OCB:case t.ALGORITHM.AES_192_OCB:case t.ALGORITHM.AES_256_OCB:return 8;case t.ALGORITHM.CHACHA_20_POLY:return 12;default:return O(e.iv||t.IV_LENGTH.default,t.IV_LENGTH.min,t.IV_LENGTH.max)}}static GetKeyLength(a=t.DEFAULT_ALGORITHM.buffer){switch(a){case t.ALGORITHM.CHACHA_20_POLY:return{algorithm:a,keyLength:256/8};case t.ALGORITHM.AES_128_CBC:case t.ALGORITHM.AES_128_CCM:case t.ALGORITHM.AES_128_GCM:case t.ALGORITHM.AES_128_OCB:return{algorithm:a,keyLength:128/8};case t.ALGORITHM.AES_192_CBC:case t.ALGORITHM.AES_192_CCM:case t.ALGORITHM.AES_192_GCM:case t.ALGORITHM.AES_192_OCB:return{algorithm:a,keyLength:192/8};case t.ALGORITHM.AES_256_CBC:case t.ALGORITHM.AES_256_CCM:case t.ALGORITHM.AES_256_GCM:case t.ALGORITHM.AES_256_OCB:default:return{algorithm:a,keyLength:256/8}}}static IsGCM(a){return a===t.ALGORITHM.AES_128_GCM||a===t.ALGORITHM.AES_192_GCM||a===t.ALGORITHM.AES_256_GCM}static IsCCM(a){return a===t.ALGORITHM.AES_128_CCM||a===t.ALGORITHM.AES_192_CCM||a===t.ALGORITHM.AES_256_CCM}static IsChacha20Poly(a){return a===t.ALGORITHM.CHACHA_20_POLY}static IsOCB(a){return a===t.ALGORITHM.AES_128_OCB||a===t.ALGORITHM.AES_192_OCB||a===t.ALGORITHM.AES_256_OCB}static IsCBC(a){return a===t.ALGORITHM.AES_128_CBC||a===t.ALGORITHM.AES_192_CBC||a===t.ALGORITHM.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.ALGORITHM={AES_128_CBC:"aes-128-cbc",AES_192_CBC:"aes-192-cbc",AES_256_CBC:"aes-256-cbc",AES_128_CCM:"aes-128-ccm",AES_192_CCM:"aes-192-ccm",AES_256_CCM:"aes-256-ccm",AES_128_GCM:"aes-128-gcm",AES_192_GCM:"aes-192-gcm",AES_256_GCM:"aes-256-gcm",AES_128_OCB:"aes-128-ocb",AES_192_OCB:"aes-192-ocb",AES_256_OCB:"aes-256-ocb",CHACHA_20_POLY:"chacha20-poly1305"},t.DEFAULT_ALGORITHM={buffer:t.ALGORITHM.AES_256_GCM,stream:t.ALGORITHM.AES_256_CBC},t.ALGORITHMS=Object.values(t.ALGORITHM),t.stream={Encrypt(a,e){e.algorithm||(e.algorithm=t.DEFAULT_ALGORITHM.stream);let{Key:s,IV:r,salt:n,options:{input:o,output:c,algorithm:A}}=t.NewKeyIV({secret:a,...e}),p=i.createCipheriv(A,s,r);return c.write(Buffer.concat([n,r])),t.stream.Cipher({cipher:p,input:o,output:c})},async Decrypt(a,e){e.algorithm||(e.algorithm=t.DEFAULT_ALGORITHM.stream);let{input:s,output:r,algorithm:n,length:o,salt:c,iv:A}=t.ResolveOptions(e),[p,h]=await E(s,c+A),y=p.subarray(0,c),C=p.subarray(c),L=i.scryptSync(T(a),y,o),I=i.createDecipheriv(n,L,C);return t.stream.Decipher({decipher:I,input:h,output:r})},HybridEncrypt(a,e){e.algorithm||(e.algorithm=t.DEFAULT_ALGORITHM.stream);let{Key:s,IV:r,options:{algorithm:n,input:o,output:c}}=t.NewKeyIV(e),A=i.publicEncrypt({key:a,padding:i.constants.RSA_PKCS1_OAEP_PADDING,oaepHash:"sha256"},Buffer.concat([s,r])),p=i.createCipheriv(n,s,r);return t.stream.Cipher({cipher:p,encryptedKey:A,input:o,output:c})},HybridDecrypt(a,e){let{input:s,output:r}=e,{keyLength:n,algorithm:o}=t.GetKeyLength(e.algorithm||t.DEFAULT_ALGORITHM.stream);return new Promise((c,A)=>(s.on("error",A),r.on("error",A),t._stream.ExtractKeyLength(s).then(t._stream.ExtractKeyIV).then(([p,h])=>({...t.DecryptKeyIV({privateKey:a,EncryptedKeyIV:p,keyLength:n}),input:h})).then(async({Key:p,IV:h,input:y})=>{y.on("error",A);let C=i.createDecipheriv(o,p,h);await t.stream.Decipher({decipher:C,input:y,output:r}),c()}).catch(A)))},Cipher(a){let{cipher:e,encryptedKey:s,input:r,output:n}=a;return new Promise((o,c)=>{e.on("error",c),r.on("error",c),n.on("error",c),n.on("finish",o),s&&(n.write(m(s.length)),n.write(s)),r.pipe(e).pipe(n)})},Decipher(a){let{decipher:e,input:s,output:r}=a;return new Promise((n,o)=>{e.on("error",o),s.on("error",o),r.on("error",o),r.on("finish",n),s.pipe(e).pipe(r)})}},t._stream={ExtractKeyLength(a){return E(a,4).then(([e,s])=>[l(e),s])},ExtractKeyIV([a,e]){return E(e,a)}};var d=t;export{d as Cipher};
package/dist/types.d.mts CHANGED
@@ -1,115 +1,4 @@
1
- import crypto from 'crypto';
2
- import { Readable, Writable } from 'stream';
3
- import { CoerceToUint8ArrayInput } from '@alessiofrittoli/crypto-buffer';
4
-
5
- /**
6
- * Cipher types.
7
- */
8
- declare namespace Cph {
9
- /** Cipher CBC algorithm types. */
10
- type CBCTypes = 'aes-128-cbc' | 'aes-192-cbc' | 'aes-256-cbc';
11
- /** Cipher supported algorithm types. */
12
- type AesAlgorithm = (crypto.CipherCCMTypes | crypto.CipherGCMTypes | crypto.CipherOCBTypes | Cph.CBCTypes | crypto.CipherChaCha20Poly1305Types);
13
- /**
14
- * Common Cipher options.
15
- * @template T The AES algorithm type.
16
- */
17
- interface Options<T extends Cph.AesAlgorithm = Cph.AesAlgorithm> {
18
- /** The Cipher algorithm to use. Default: `aes-256-gcm` | `aes-256-cbc`. */
19
- algorithm?: T;
20
- /** The salt length. Minimum: `16`, Maximum: `64`. Default: `32`. */
21
- salt?: number;
22
- /** The `IV` length. Minimum: `8`, Maximum: `32`. Default: `16`. */
23
- iv?: number;
24
- /** The `authTag` length. Minimum: `4`, Maximum: `16`. Default: `16`. */
25
- authTag?: number;
26
- /** Custom `Additional Authenticated Data`. */
27
- aad?: CoerceToUint8ArrayInput;
28
- /** The `AAD` length. Minimum: `16`, Maximum: `128`. Default: `32`. */
29
- aadLength?: number;
30
- }
31
- /**
32
- * Resolved Common options.
33
- */
34
- interface ResolvedOptions<T extends Cph.AesAlgorithm = Cph.AesAlgorithm> extends Required<Omit<Cph.Options<T>, 'aad'>> {
35
- /** The symmetric key length. */
36
- length: number;
37
- aad?: Uint8Array;
38
- }
39
- namespace Stream {
40
- namespace Symmetric {
41
- /**
42
- * Options for encrypting a stream.
43
- */
44
- interface EncryptOptions extends Cph.Options<Cph.CBCTypes> {
45
- /** The `Readable` Stream from where raw data to encrypt is read. */
46
- input: Readable;
47
- /** The `Writable` Stream where encrypted data is written. */
48
- output: Writable;
49
- }
50
- /**
51
- * Resolved Stream Encrypt options (symmetric and hybrid).
52
- */
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
- }
63
- /**
64
- * Options for decrypting a stream (symmetric).
65
- */
66
- interface DecryptOptions extends Cph.Stream.Symmetric.EncryptOptions {
67
- /** The `Readable` Stream from where encrypted data is read. */
68
- input: Readable;
69
- /** The `Writable` Stream where decrypted data is written. */
70
- output: Writable;
71
- }
72
- /**
73
- * Resolved Stream Decrypt options (symmetric).
74
- */
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
- }
82
- }
83
- namespace Hybrid {
84
- /**
85
- * Alias for {@link Cph.Stream.Symmetric.EncryptOptions}
86
- */
87
- type EncryptOptions = Cph.Stream.Symmetric.EncryptOptions;
88
- /**
89
- * Alias for {@link Cph.Stream.Symmetric.EncryptResolvedOptions}
90
- */
91
- type EncryptResolvedOptions = Cph.Stream.Symmetric.EncryptResolvedOptions;
92
- /**
93
- * Options for decrypting a stream.
94
- */
95
- interface DecryptOptions extends Cph.Stream.Symmetric.DecryptOptions {
96
- /** The RSA key length in bytes used while encrypting data. This is used to properly extract the encrypted Cipher Key and Initialization Vector. */
97
- rsaKeyLength: number;
98
- }
99
- /**
100
- * Resolved Stream Decrypt options.
101
- */
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;
111
- }
112
- }
113
- }
114
-
115
- export { Cph };
1
+ import 'crypto';
2
+ import 'stream';
3
+ import '@alessiofrittoli/crypto-buffer';
4
+ export { C as Cph } from './index-B9WIVWrs.mjs';
package/dist/types.d.ts CHANGED
@@ -1,115 +1,4 @@
1
- import crypto from 'crypto';
2
- import { Readable, Writable } from 'stream';
3
- import { CoerceToUint8ArrayInput } from '@alessiofrittoli/crypto-buffer';
4
-
5
- /**
6
- * Cipher types.
7
- */
8
- declare namespace Cph {
9
- /** Cipher CBC algorithm types. */
10
- type CBCTypes = 'aes-128-cbc' | 'aes-192-cbc' | 'aes-256-cbc';
11
- /** Cipher supported algorithm types. */
12
- type AesAlgorithm = (crypto.CipherCCMTypes | crypto.CipherGCMTypes | crypto.CipherOCBTypes | Cph.CBCTypes | crypto.CipherChaCha20Poly1305Types);
13
- /**
14
- * Common Cipher options.
15
- * @template T The AES algorithm type.
16
- */
17
- interface Options<T extends Cph.AesAlgorithm = Cph.AesAlgorithm> {
18
- /** The Cipher algorithm to use. Default: `aes-256-gcm` | `aes-256-cbc`. */
19
- algorithm?: T;
20
- /** The salt length. Minimum: `16`, Maximum: `64`. Default: `32`. */
21
- salt?: number;
22
- /** The `IV` length. Minimum: `8`, Maximum: `32`. Default: `16`. */
23
- iv?: number;
24
- /** The `authTag` length. Minimum: `4`, Maximum: `16`. Default: `16`. */
25
- authTag?: number;
26
- /** Custom `Additional Authenticated Data`. */
27
- aad?: CoerceToUint8ArrayInput;
28
- /** The `AAD` length. Minimum: `16`, Maximum: `128`. Default: `32`. */
29
- aadLength?: number;
30
- }
31
- /**
32
- * Resolved Common options.
33
- */
34
- interface ResolvedOptions<T extends Cph.AesAlgorithm = Cph.AesAlgorithm> extends Required<Omit<Cph.Options<T>, 'aad'>> {
35
- /** The symmetric key length. */
36
- length: number;
37
- aad?: Uint8Array;
38
- }
39
- namespace Stream {
40
- namespace Symmetric {
41
- /**
42
- * Options for encrypting a stream.
43
- */
44
- interface EncryptOptions extends Cph.Options<Cph.CBCTypes> {
45
- /** The `Readable` Stream from where raw data to encrypt is read. */
46
- input: Readable;
47
- /** The `Writable` Stream where encrypted data is written. */
48
- output: Writable;
49
- }
50
- /**
51
- * Resolved Stream Encrypt options (symmetric and hybrid).
52
- */
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
- }
63
- /**
64
- * Options for decrypting a stream (symmetric).
65
- */
66
- interface DecryptOptions extends Cph.Stream.Symmetric.EncryptOptions {
67
- /** The `Readable` Stream from where encrypted data is read. */
68
- input: Readable;
69
- /** The `Writable` Stream where decrypted data is written. */
70
- output: Writable;
71
- }
72
- /**
73
- * Resolved Stream Decrypt options (symmetric).
74
- */
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
- }
82
- }
83
- namespace Hybrid {
84
- /**
85
- * Alias for {@link Cph.Stream.Symmetric.EncryptOptions}
86
- */
87
- type EncryptOptions = Cph.Stream.Symmetric.EncryptOptions;
88
- /**
89
- * Alias for {@link Cph.Stream.Symmetric.EncryptResolvedOptions}
90
- */
91
- type EncryptResolvedOptions = Cph.Stream.Symmetric.EncryptResolvedOptions;
92
- /**
93
- * Options for decrypting a stream.
94
- */
95
- interface DecryptOptions extends Cph.Stream.Symmetric.DecryptOptions {
96
- /** The RSA key length in bytes used while encrypting data. This is used to properly extract the encrypted Cipher Key and Initialization Vector. */
97
- rsaKeyLength: number;
98
- }
99
- /**
100
- * Resolved Stream Decrypt options.
101
- */
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;
111
- }
112
- }
113
- }
114
-
115
- export { Cph };
1
+ import 'crypto';
2
+ import 'stream';
3
+ import '@alessiofrittoli/crypto-buffer';
4
+ export { C as Cph } from './index-B9WIVWrs.js';