nestjs-cryptography 3.0.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SECURITY.md +14 -0
- package/dist/constants.d.ts +15 -0
- package/dist/constants.js +16 -1
- package/dist/cryptography.service.d.ts +3 -2
- package/dist/cryptography.service.js +101 -21
- package/dist/interfaces/cryptography-options.interface.d.ts +20 -16
- package/package.json +23 -16
- package/wiki/README.md +0 -41
- package/wiki/babel.config.js +0 -3
- package/wiki/docs/Internals/_category_.json +0 -7
- package/wiki/docs/Internals/create-safe-random-data.mdx +0 -41
- package/wiki/docs/Internals/create-secure-hmac.mdx +0 -31
- package/wiki/docs/Internals/symmetric-data-encrypt.mdx +0 -103
- package/wiki/docs/Internals/symmetric-secure-data-encrypt.mdx +0 -161
- package/wiki/docs/api-reference/_category_.json +0 -7
- package/wiki/docs/api-reference/settings.mdx +0 -199
- package/wiki/docs/guides/_category_.json +0 -7
- package/wiki/docs/guides/generics.mdx +0 -170
- package/wiki/docs/guides/hashing.mdx +0 -258
- package/wiki/docs/guides/hmac.mdx +0 -271
- package/wiki/docs/guides/key-derivation.mdx +0 -101
- package/wiki/docs/guides/password-hashing.mdx +0 -136
- package/wiki/docs/guides/symmetric-encryption.mdx +0 -272
- package/wiki/docs/intro.mdx +0 -148
- package/wiki/docusaurus.config.ts +0 -138
- package/wiki/package.json +0 -48
- package/wiki/sidebars.ts +0 -20
- package/wiki/src/common/timing-attack.mdx +0 -3
- package/wiki/src/common/tips.mdx +0 -18
- package/wiki/src/components/GenerateHexButton/index.tsx +0 -35
- package/wiki/src/components/GenerateHexButton/styles.module.css +0 -10
- package/wiki/src/components/GenericLabel/index.tsx +0 -19
- package/wiki/src/components/HomepageFeatures/index.tsx +0 -70
- package/wiki/src/components/HomepageFeatures/styles.module.css +0 -11
- package/wiki/src/components/RecommendedLabel/index.tsx +0 -19
- package/wiki/src/components/RequiredLabel/index.tsx +0 -12
- package/wiki/src/css/custom.css +0 -30
- package/wiki/src/pages/index.module.css +0 -23
- package/wiki/src/pages/index.tsx +0 -43
- package/wiki/src/pages/markdown-page.md +0 -7
- package/wiki/static/.nojekyll +0 -0
- package/wiki/static/img/gear_api.png +0 -0
- package/wiki/static/img/logo.svg +0 -1
- package/wiki/static/img/nestjs_favicon.ico +0 -0
- package/wiki/static/img/node_crypto.png +0 -0
- package/wiki/static/img/phc_logo.png +0 -0
- package/wiki/static/img/profile.png +0 -0
- package/wiki/versioned_docs/version-2.x/Internals/_category_.json +0 -8
- package/wiki/versioned_docs/version-2.x/Internals/create-secure-hmac.mdx +0 -30
- package/wiki/versioned_docs/version-2.x/Internals/symmetric-secure-data-encrypt.mdx +0 -160
- package/wiki/versioned_docs/version-2.x/api-reference/_category_.json +0 -8
- package/wiki/versioned_docs/version-2.x/api-reference/settings.mdx +0 -197
- package/wiki/versioned_docs/version-2.x/guides/_category_.json +0 -7
- package/wiki/versioned_docs/version-2.x/guides/generics.mdx +0 -133
- package/wiki/versioned_docs/version-2.x/guides/hashing.mdx +0 -229
- package/wiki/versioned_docs/version-2.x/guides/hmac.mdx +0 -198
- package/wiki/versioned_docs/version-2.x/guides/key-derivation.mdx +0 -98
- package/wiki/versioned_docs/version-2.x/guides/password-hashing.mdx +0 -132
- package/wiki/versioned_docs/version-2.x/guides/symmetric-encryption.mdx +0 -107
- package/wiki/versioned_docs/version-2.x/intro.mdx +0 -148
- package/wiki/versioned_sidebars/version-2.x-sidebars.json +0 -8
- package/wiki/versions.json +0 -3
package/SECURITY.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
currently being supported with security updates.
|
|
6
|
+
|
|
7
|
+
| Version | Supported |
|
|
8
|
+
| ------- | ------------------ |
|
|
9
|
+
| 3.x | :white_check_mark: |
|
|
10
|
+
| 2.x | :x: |
|
|
11
|
+
|
|
12
|
+
## Reporting a Vulnerability
|
|
13
|
+
|
|
14
|
+
Please report security issues to security@thewolfx41.dev
|
package/dist/constants.d.ts
CHANGED
|
@@ -1 +1,16 @@
|
|
|
1
|
+
import { Argon2Type } from './interfaces';
|
|
1
2
|
export declare const CRYPTOGRAPHY_OPTIONS = "CRYPTOGRAPHY_OPTIONS";
|
|
3
|
+
export declare const DEFAULT_KDF_CRYPTOGRAPHY_OPTIONS: {
|
|
4
|
+
outputKeyLength: number;
|
|
5
|
+
argon2Type: Argon2Type;
|
|
6
|
+
memoryCost: number;
|
|
7
|
+
timeCost: number;
|
|
8
|
+
};
|
|
9
|
+
export declare const DEFAULT_HASHING_CRYPTOGRAPHY_OPTIONS: {
|
|
10
|
+
password: {
|
|
11
|
+
outputKeyLength: number;
|
|
12
|
+
argon2Type: Argon2Type;
|
|
13
|
+
memoryCost: number;
|
|
14
|
+
timeCost: number;
|
|
15
|
+
};
|
|
16
|
+
};
|
package/dist/constants.js
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CRYPTOGRAPHY_OPTIONS = void 0;
|
|
3
|
+
exports.DEFAULT_HASHING_CRYPTOGRAPHY_OPTIONS = exports.DEFAULT_KDF_CRYPTOGRAPHY_OPTIONS = exports.CRYPTOGRAPHY_OPTIONS = void 0;
|
|
4
|
+
const interfaces_1 = require("./interfaces");
|
|
4
5
|
exports.CRYPTOGRAPHY_OPTIONS = 'CRYPTOGRAPHY_OPTIONS';
|
|
6
|
+
exports.DEFAULT_KDF_CRYPTOGRAPHY_OPTIONS = {
|
|
7
|
+
outputKeyLength: 32,
|
|
8
|
+
argon2Type: interfaces_1.Argon2Type.argon2i,
|
|
9
|
+
memoryCost: 65536,
|
|
10
|
+
timeCost: 3,
|
|
11
|
+
};
|
|
12
|
+
exports.DEFAULT_HASHING_CRYPTOGRAPHY_OPTIONS = {
|
|
13
|
+
password: {
|
|
14
|
+
outputKeyLength: 64,
|
|
15
|
+
argon2Type: interfaces_1.Argon2Type.argon2id,
|
|
16
|
+
memoryCost: 131072,
|
|
17
|
+
timeCost: 4,
|
|
18
|
+
},
|
|
19
|
+
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as crypto from 'node:crypto';
|
|
2
2
|
import { CryptographyOptionsInterface, GenericOptionsInterface } from './interfaces';
|
|
3
3
|
export declare class CryptographyService {
|
|
4
|
-
private
|
|
5
|
-
constructor(
|
|
4
|
+
private moduleOptions;
|
|
5
|
+
constructor(moduleOptions: CryptographyOptionsInterface);
|
|
6
6
|
private convertInputData;
|
|
7
|
+
private checkModuleOptions;
|
|
7
8
|
private extractIV;
|
|
8
9
|
private extractAuthTagFromCypheredData;
|
|
9
10
|
private extractCipheredData;
|
|
@@ -21,13 +21,23 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
21
21
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
22
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
23
|
};
|
|
24
|
-
var __importStar = (this && this.__importStar) || function (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
31
41
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
32
42
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
33
43
|
};
|
|
@@ -40,9 +50,10 @@ const crypto = __importStar(require("node:crypto"));
|
|
|
40
50
|
const argon2 = __importStar(require("argon2"));
|
|
41
51
|
const common_1 = require("@nestjs/common");
|
|
42
52
|
const cryptography_module_definition_1 = require("./cryptography.module-definition");
|
|
53
|
+
const constants_1 = require("./constants");
|
|
43
54
|
let CryptographyService = class CryptographyService {
|
|
44
|
-
constructor(
|
|
45
|
-
this.
|
|
55
|
+
constructor(moduleOptions) {
|
|
56
|
+
this.moduleOptions = moduleOptions;
|
|
46
57
|
}
|
|
47
58
|
convertInputData(data, inputEncoding) {
|
|
48
59
|
if (Buffer.isBuffer(data)) {
|
|
@@ -55,6 +66,15 @@ let CryptographyService = class CryptographyService {
|
|
|
55
66
|
throw new Error('Unsupported input type');
|
|
56
67
|
}
|
|
57
68
|
}
|
|
69
|
+
checkModuleOptions(parent, options) {
|
|
70
|
+
for (const option in options) {
|
|
71
|
+
if (typeof option === 'object')
|
|
72
|
+
this.checkModuleOptions(parent, option);
|
|
73
|
+
if (options[option] === undefined || options[option] === null) {
|
|
74
|
+
throw new Error(`[CryptographyModule] [${parent}] Option ${option} is not defined on the configuration`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
58
78
|
extractIV(data) {
|
|
59
79
|
return data.subarray(0, 12);
|
|
60
80
|
}
|
|
@@ -94,21 +114,69 @@ let CryptographyService = class CryptographyService {
|
|
|
94
114
|
return crypto.generateKeySync('hmac', { length });
|
|
95
115
|
}
|
|
96
116
|
async deriveMasterKey(masterKey, salt, length) {
|
|
117
|
+
if (!this.moduleOptions?.useDefaultValues) {
|
|
118
|
+
this.checkModuleOptions('KDF', {
|
|
119
|
+
...(!length && {
|
|
120
|
+
outputKeyLength: this.moduleOptions?.kdf?.outputKeyLength,
|
|
121
|
+
}),
|
|
122
|
+
argon2Type: this.moduleOptions?.kdf?.argon2Type,
|
|
123
|
+
memoryCost: this.moduleOptions?.kdf?.memoryCost,
|
|
124
|
+
timeCost: this.moduleOptions?.kdf?.timeCost,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
this.moduleOptions.kdf = {
|
|
129
|
+
...this.moduleOptions?.kdf,
|
|
130
|
+
};
|
|
131
|
+
this.moduleOptions.kdf.outputKeyLength =
|
|
132
|
+
constants_1.DEFAULT_KDF_CRYPTOGRAPHY_OPTIONS.outputKeyLength;
|
|
133
|
+
this.moduleOptions.kdf.argon2Type =
|
|
134
|
+
constants_1.DEFAULT_KDF_CRYPTOGRAPHY_OPTIONS.argon2Type;
|
|
135
|
+
this.moduleOptions.kdf.memoryCost =
|
|
136
|
+
constants_1.DEFAULT_KDF_CRYPTOGRAPHY_OPTIONS.memoryCost;
|
|
137
|
+
this.moduleOptions.kdf.timeCost =
|
|
138
|
+
constants_1.DEFAULT_KDF_CRYPTOGRAPHY_OPTIONS.timeCost;
|
|
139
|
+
}
|
|
140
|
+
console.log(this.moduleOptions.kdf);
|
|
97
141
|
return await argon2.hash(masterKey, {
|
|
98
|
-
hashLength: length ?? this.
|
|
142
|
+
hashLength: length ?? this.moduleOptions.kdf.outputKeyLength,
|
|
99
143
|
salt: salt,
|
|
100
|
-
type: this.
|
|
101
|
-
memoryCost: this.
|
|
102
|
-
timeCost: this.
|
|
144
|
+
type: this.moduleOptions.kdf.argon2Type,
|
|
145
|
+
memoryCost: this.moduleOptions.kdf.memoryCost,
|
|
146
|
+
timeCost: this.moduleOptions.kdf.timeCost,
|
|
103
147
|
raw: true,
|
|
104
148
|
});
|
|
105
149
|
}
|
|
106
150
|
async createArgon2HashFromPassword(data) {
|
|
151
|
+
if (!this.moduleOptions?.useDefaultValues) {
|
|
152
|
+
this.checkModuleOptions('HASHING_PASSWORD', {
|
|
153
|
+
outputKeyLength: this.moduleOptions?.hashing?.password?.outputKeyLength,
|
|
154
|
+
argon2Type: this.moduleOptions?.hashing?.password?.argon2Type,
|
|
155
|
+
memoryCost: this.moduleOptions?.hashing?.password?.memoryCost,
|
|
156
|
+
timeCost: this.moduleOptions?.hashing?.password?.timeCost,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
this.moduleOptions.hashing = {
|
|
161
|
+
...this.moduleOptions?.hashing,
|
|
162
|
+
password: {
|
|
163
|
+
...this.moduleOptions.hashing?.password,
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
this.moduleOptions.hashing.password.outputKeyLength =
|
|
167
|
+
constants_1.DEFAULT_HASHING_CRYPTOGRAPHY_OPTIONS.password.outputKeyLength;
|
|
168
|
+
this.moduleOptions.hashing.password.argon2Type =
|
|
169
|
+
constants_1.DEFAULT_HASHING_CRYPTOGRAPHY_OPTIONS.password.argon2Type;
|
|
170
|
+
this.moduleOptions.hashing.password.memoryCost =
|
|
171
|
+
constants_1.DEFAULT_HASHING_CRYPTOGRAPHY_OPTIONS.password.memoryCost;
|
|
172
|
+
this.moduleOptions.hashing.password.timeCost =
|
|
173
|
+
constants_1.DEFAULT_HASHING_CRYPTOGRAPHY_OPTIONS.password.timeCost;
|
|
174
|
+
}
|
|
107
175
|
const tmpData = await argon2.hash(data, {
|
|
108
|
-
hashLength: this.
|
|
109
|
-
type: this.
|
|
110
|
-
memoryCost: this.
|
|
111
|
-
timeCost: this.
|
|
176
|
+
hashLength: this.moduleOptions.hashing.password.outputKeyLength,
|
|
177
|
+
type: this.moduleOptions.hashing.password.argon2Type,
|
|
178
|
+
memoryCost: this.moduleOptions.hashing.password.memoryCost,
|
|
179
|
+
timeCost: this.moduleOptions.hashing.password.timeCost,
|
|
112
180
|
raw: false,
|
|
113
181
|
});
|
|
114
182
|
return Buffer.isBuffer(tmpData) ? tmpData : Buffer.from(tmpData);
|
|
@@ -155,14 +223,20 @@ let CryptographyService = class CryptographyService {
|
|
|
155
223
|
return crypto.timingSafeEqual(hmac, inputOldHmacData);
|
|
156
224
|
}
|
|
157
225
|
createSecureHmac(data, options) {
|
|
158
|
-
|
|
226
|
+
this.checkModuleOptions('HMAC', {
|
|
227
|
+
masterKey: this.moduleOptions?.hashing?.hmac?.masterKey,
|
|
228
|
+
});
|
|
229
|
+
const key = Buffer.from(this.moduleOptions.hashing.hmac.masterKey, 'hex');
|
|
159
230
|
const salt = crypto.randomBytes(16);
|
|
160
231
|
const secureKey = this.createHmacSecureKey(key, salt);
|
|
161
232
|
const hmac = this.createCustomHmac('sha3-256', secureKey, data, options);
|
|
162
233
|
return Buffer.concat([salt, hmac], salt.length + hmac.length);
|
|
163
234
|
}
|
|
164
235
|
verifySecureHmac(data, oldHmac, options) {
|
|
165
|
-
|
|
236
|
+
this.checkModuleOptions('HMAC', {
|
|
237
|
+
masterKey: this.moduleOptions?.hashing?.hmac?.masterKey,
|
|
238
|
+
});
|
|
239
|
+
const key = Buffer.from(this.moduleOptions.hashing.hmac.masterKey, 'hex');
|
|
166
240
|
const buffOldHmac = this.convertInputData(oldHmac, options?.inputDataEncoding);
|
|
167
241
|
const saltOldHmac = this.extractSaltFromHmac(buffOldHmac);
|
|
168
242
|
const hashOldHmac = buffOldHmac.subarray(16, buffOldHmac.length);
|
|
@@ -200,16 +274,22 @@ let CryptographyService = class CryptographyService {
|
|
|
200
274
|
return decipheredData;
|
|
201
275
|
}
|
|
202
276
|
async symmetricSecureDataEncrypt(data, options) {
|
|
277
|
+
this.checkModuleOptions('SYMMETRIC_ENCRYPTION', {
|
|
278
|
+
masterKey: this.moduleOptions?.encryption?.symmetric?.masterKey,
|
|
279
|
+
});
|
|
203
280
|
const dek = this.createSafeRandomData(32);
|
|
204
281
|
const cipheredData = await this.symmetricDataEncrypt(data, dek, options);
|
|
205
|
-
const cipheredDek = await this.symmetricDataEncrypt(dek, this.
|
|
282
|
+
const cipheredDek = await this.symmetricDataEncrypt(dek, this.moduleOptions.encryption.symmetric.masterKey);
|
|
206
283
|
return Buffer.concat([cipheredDek, cipheredData]);
|
|
207
284
|
}
|
|
208
285
|
async symmetricSecureDataDecrypt(data, options) {
|
|
286
|
+
this.checkModuleOptions('SYMMETRIC_ENCRYPTION', {
|
|
287
|
+
masterKey: this.moduleOptions?.encryption?.symmetric?.masterKey,
|
|
288
|
+
});
|
|
209
289
|
const inputData = this.convertInputData(data, options?.inputDataEncoding);
|
|
210
290
|
const cipheredDek = this.extractCipheredDEK(inputData);
|
|
211
291
|
const cipheredData = this.extractCipheredDataWithDEK(inputData);
|
|
212
|
-
const decipheredDek = await this.symmetricDataDecrypt(cipheredDek, this.
|
|
292
|
+
const decipheredDek = await this.symmetricDataDecrypt(cipheredDek, this.moduleOptions.encryption.symmetric.masterKey);
|
|
213
293
|
return await this.symmetricDataDecrypt(cipheredData, decipheredDek);
|
|
214
294
|
}
|
|
215
295
|
};
|
|
@@ -3,27 +3,31 @@ export declare enum Argon2Type {
|
|
|
3
3
|
argon2i = 1,
|
|
4
4
|
argon2id = 2
|
|
5
5
|
}
|
|
6
|
-
export interface
|
|
7
|
-
|
|
6
|
+
export interface CryptographyKdfOptions {
|
|
7
|
+
outputKeyLength: number;
|
|
8
|
+
argon2Type: Argon2Type;
|
|
9
|
+
memoryCost: number;
|
|
10
|
+
timeCost: number;
|
|
11
|
+
}
|
|
12
|
+
export interface CryptographyHashingOptions {
|
|
13
|
+
password: {
|
|
8
14
|
outputKeyLength: number;
|
|
9
15
|
argon2Type: Argon2Type;
|
|
10
16
|
memoryCost: number;
|
|
11
17
|
timeCost: number;
|
|
12
18
|
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
outputKeyLength: number;
|
|
16
|
-
argon2Type: Argon2Type;
|
|
17
|
-
memoryCost: number;
|
|
18
|
-
timeCost: number;
|
|
19
|
-
};
|
|
20
|
-
hmac: {
|
|
21
|
-
masterKey: string;
|
|
22
|
-
};
|
|
19
|
+
hmac: {
|
|
20
|
+
masterKey: string;
|
|
23
21
|
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
}
|
|
23
|
+
export interface CryptographyEncryptionOptions {
|
|
24
|
+
symmetric: {
|
|
25
|
+
masterKey: string;
|
|
28
26
|
};
|
|
29
27
|
}
|
|
28
|
+
export interface CryptographyOptionsInterface {
|
|
29
|
+
useDefaultValues?: boolean;
|
|
30
|
+
kdf?: Partial<CryptographyKdfOptions>;
|
|
31
|
+
hashing?: Partial<CryptographyHashingOptions>;
|
|
32
|
+
encryption?: Partial<CryptographyEncryptionOptions>;
|
|
33
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nestjs-cryptography",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "Marc Jorge Gonzalez",
|
|
6
6
|
"url": "https://github.com/mjorgegulab"
|
|
@@ -30,39 +30,46 @@
|
|
|
30
30
|
"argon2": "^0.41.1"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@nestjs/cli": "^
|
|
34
|
-
"@nestjs/common": "^
|
|
35
|
-
"@nestjs/core": "^
|
|
36
|
-
"@nestjs/platform-express": "^
|
|
37
|
-
"@nestjs/schematics": "^
|
|
38
|
-
"@nestjs/testing": "^
|
|
39
|
-
"@types/express": "^
|
|
40
|
-
"@types/jest": "29.5.
|
|
41
|
-
"@types/node": "22.
|
|
33
|
+
"@nestjs/cli": "^11.0.4",
|
|
34
|
+
"@nestjs/common": "^11.0.10",
|
|
35
|
+
"@nestjs/core": "^11.0.10",
|
|
36
|
+
"@nestjs/platform-express": "^11.0.10",
|
|
37
|
+
"@nestjs/schematics": "^11.0.1",
|
|
38
|
+
"@nestjs/testing": "^11.0.10",
|
|
39
|
+
"@types/express": "^5.0.0",
|
|
40
|
+
"@types/jest": "29.5.14",
|
|
41
|
+
"@types/node": "22.13.4",
|
|
42
42
|
"@types/supertest": "^6.0.2",
|
|
43
43
|
"@typescript-eslint/eslint-plugin": "^7.12.0",
|
|
44
44
|
"@typescript-eslint/parser": "^7.12.0",
|
|
45
45
|
"eslint": "^8.57.0",
|
|
46
46
|
"eslint-config-prettier": "^9.1.0",
|
|
47
|
-
"eslint-plugin-prettier": "^5.2.
|
|
47
|
+
"eslint-plugin-prettier": "^5.2.3",
|
|
48
48
|
"jest": "29.7.0",
|
|
49
|
-
"prettier": "^3.
|
|
49
|
+
"prettier": "^3.5.1",
|
|
50
50
|
"reflect-metadata": "^0.2.2",
|
|
51
51
|
"rimraf": "^6.0.1",
|
|
52
52
|
"rxjs": "^7.8.1",
|
|
53
53
|
"source-map-support": "^0.5.21",
|
|
54
54
|
"supertest": "^7.0.0",
|
|
55
55
|
"ts-jest": "29.2.5",
|
|
56
|
-
"ts-loader": "^9.5.
|
|
56
|
+
"ts-loader": "^9.5.2",
|
|
57
57
|
"ts-node": "^10.9.2",
|
|
58
58
|
"tsconfig-paths": "4.2.0",
|
|
59
|
-
"typescript": "^5.
|
|
59
|
+
"typescript": "^5.7.3"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
|
-
"@nestjs/common": "^9.0.0 || ^10.0.0",
|
|
63
|
-
"@nestjs/core": "^9.0.0 || ^10.0.0"
|
|
62
|
+
"@nestjs/common": "^9.0.0 || ^10.0.0 || ^11.0.0",
|
|
63
|
+
"@nestjs/core": "^9.0.0 || ^10.0.0 || ^11.0.0"
|
|
64
64
|
},
|
|
65
65
|
"jest": {
|
|
66
|
+
"testPathIgnorePatterns": [
|
|
67
|
+
"/node_modules/",
|
|
68
|
+
"/wiki/"
|
|
69
|
+
],
|
|
70
|
+
"modulePathIgnorePatterns": [
|
|
71
|
+
"/wiki/"
|
|
72
|
+
],
|
|
66
73
|
"moduleFileExtensions": [
|
|
67
74
|
"js",
|
|
68
75
|
"json",
|
package/wiki/README.md
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# Website
|
|
2
|
-
|
|
3
|
-
This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
|
|
4
|
-
|
|
5
|
-
### Installation
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
$ yarn
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
### Local Development
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
$ yarn start
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
|
|
18
|
-
|
|
19
|
-
### Build
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
$ yarn build
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
This command generates static content into the `build` directory and can be served using any static contents hosting service.
|
|
26
|
-
|
|
27
|
-
### Deployment
|
|
28
|
-
|
|
29
|
-
Using SSH:
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
$ USE_SSH=true yarn deploy
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Not using SSH:
|
|
36
|
-
|
|
37
|
-
```
|
|
38
|
-
$ GIT_USER=<Your GitHub username> yarn deploy
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
|
package/wiki/babel.config.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Create Safe Random Data
|
|
3
|
-
sidebar_label: Create Safe Random Data
|
|
4
|
-
sidebar_position: 2
|
|
5
|
-
description: Internals of createSafeRandomData
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
In the following section, you will see a diagram of the cryptographic operations performed when calling the method [`createSafeRandomData`][1]
|
|
9
|
-
|
|
10
|
-
This method generate a cryptographically secure random bytes of the desired lengths using **HKDF**
|
|
11
|
-
with `sha3-256` digest algorithm using the following params:
|
|
12
|
-
- Generate a random key using the secure random bytes' generator.
|
|
13
|
-
- Generate a salt using the secure random bytes' generator.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
<div style={{ textAlign: 'center' }}>
|
|
17
|
-
```mermaid
|
|
18
|
-
graph TD
|
|
19
|
-
A[Key Length: length]
|
|
20
|
-
|
|
21
|
-
A --> CRB[Create Random Bytes: 64 bytes]
|
|
22
|
-
CRB --> CSK[Create Secret Key]
|
|
23
|
-
CSK ==> SK(SECRET_KEY)
|
|
24
|
-
|
|
25
|
-
A --> CRB2[Create Random Bytes: 64 bytes]
|
|
26
|
-
CRB2 ==> RB[RANDOM_BYTES]
|
|
27
|
-
|
|
28
|
-
SK -.-> HKDF["HKDF ( sha3-256 + SECRET_KEY + RANDOM_BYTES + length )"]
|
|
29
|
-
RB -.-> HKDF --> F([Return Secure Random Bytes])
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
style CRB fill:#f9f,stroke:#333,stroke-width:2px
|
|
33
|
-
style CRB2 fill:#f9f,stroke:#333,stroke-width:2px
|
|
34
|
-
style SK fill:#bbf,stroke:#333,stroke-width:2px
|
|
35
|
-
style RB fill:#bbf,stroke:#333,stroke-width:2px
|
|
36
|
-
style HKDF fill:#bfb,stroke:#333,stroke-width:2px
|
|
37
|
-
style F fill:#00f0f0,stroke:#F0000,stroke-width:2px
|
|
38
|
-
```
|
|
39
|
-
</div>
|
|
40
|
-
|
|
41
|
-
[1]: ../guides/generics#generate-secure-random-data
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Create Secure HMAC
|
|
3
|
-
sidebar_label: Create Secure HMAC
|
|
4
|
-
sidebar_position: 1
|
|
5
|
-
description: Internals of createSecureHmac
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
In the following section, you will see a diagram of the cryptographic operations performed when calling the method [`createSecureHmac`][1]
|
|
9
|
-
|
|
10
|
-
This method performs several cryptographic operations, including generating a salt,
|
|
11
|
-
deriving a secure key using HKDF with the sha3-256 hashing algorithm, creating an HMAC,
|
|
12
|
-
and returning the concatenated salt and HMAC result. The diagram will illustrate these steps clearly.
|
|
13
|
-
|
|
14
|
-
<div style={{ textAlign: 'center' }}>
|
|
15
|
-
```mermaid
|
|
16
|
-
graph TD
|
|
17
|
-
A[Input Data: data] --> B[Generate Master Key from Options]
|
|
18
|
-
B --> C[Generate Random Salt: 16 bytes]
|
|
19
|
-
C --> D[Use HKDF with sha3-256, Master Key, and Salt]
|
|
20
|
-
D --> E[Generate Secure Key: 64 bytes]
|
|
21
|
-
E --> F[Create HMAC with sha3-256, Secure Key, and Data]
|
|
22
|
-
F --> G[Concatenate Salt and HMAC]
|
|
23
|
-
G --> H[Return Combined Buffer: Salt + HMAC]
|
|
24
|
-
|
|
25
|
-
style B fill:#f9f,stroke:#333,stroke-width:2px
|
|
26
|
-
style D fill:#bbf,stroke:#333,stroke-width:2px
|
|
27
|
-
style F fill:#bfb,stroke:#333,stroke-width:2px
|
|
28
|
-
```
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
[1]: ../guides/hmac#create-a-secure-hmac
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Symmetric Data Encrypt
|
|
3
|
-
sidebar_label: Symmetric Data Encrypt
|
|
4
|
-
sidebar_position: 4
|
|
5
|
-
description: Internals of symmetricDataEncrypt
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
In the following section, you will see a diagram of the cryptographic operations performed when calling the method [`symmetricDataEncrypt`][1]
|
|
9
|
-
|
|
10
|
-
This method securely encrypts input data by first generating a 12-byte Initialization Vector **(IV)**
|
|
11
|
-
and a 64-byte **salt** using the `HKDF(sha3-256 + random_key + random_salt)` technique.
|
|
12
|
-
It then derives a secure encryption key from the salt using the **Argon2** algorithm.
|
|
13
|
-
The actual data is encrypted using **AES-256-GCM** with the derived key,
|
|
14
|
-
resulting in an output that includes the IV, salt, authentication tag, and ciphertext.
|
|
15
|
-
This comprehensive approach ensures the integrity and confidentiality of the data during storage or transmission.
|
|
16
|
-
|
|
17
|
-
## **Diagram**
|
|
18
|
-
|
|
19
|
-
<div style={{ textAlign: 'center' }}>
|
|
20
|
-
```mermaid
|
|
21
|
-
graph TD
|
|
22
|
-
|
|
23
|
-
A[Input: Data] --> ID
|
|
24
|
-
B[Input: Key] --> IK
|
|
25
|
-
|
|
26
|
-
subgraph ED[Encrypt Data]
|
|
27
|
-
|
|
28
|
-
ID(DATA)
|
|
29
|
-
IK(KEY)
|
|
30
|
-
|
|
31
|
-
subgraph IVGENERATIONGRAPH["Generate IV (12 bytes)"]
|
|
32
|
-
IVL[Key Length: length] --> CRB[Create Random Bytes: 64 bytes]
|
|
33
|
-
CRB --> CSK[Create Secret Key]
|
|
34
|
-
CSK ==> SK(SECRET_KEY)
|
|
35
|
-
|
|
36
|
-
IVL --> CRB2[Create Random Bytes: 64 bytes]
|
|
37
|
-
CRB2 ==> RB[RANDOM_BYTES]
|
|
38
|
-
|
|
39
|
-
SK -.-> HKDF["HKDF ( sha3-256 + SECRET_KEY + RANDOM_BYTES + length )"]
|
|
40
|
-
RB -.-> HKDF --> F([Return Secure Random Bytes])
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
subgraph SALTGENERATIONGRAPH["Generate Salt (64 bytes)"]
|
|
44
|
-
IVL2[Key Length: length] --> CRB23[Create Random Bytes: 64 bytes]
|
|
45
|
-
CRB23 --> CSK2[Create Secret Key]
|
|
46
|
-
CSK2 ==> SK2(SECRET_KEY)
|
|
47
|
-
|
|
48
|
-
IVL2 --> CRB22[Create Random Bytes: 64 bytes]
|
|
49
|
-
CRB22 ==> RB2[RANDOM_BYTES]
|
|
50
|
-
|
|
51
|
-
SK2 -.-> HKDF2["HKDF ( sha3-256 + SECRET_KEY + RANDOM_BYTES + length )"]
|
|
52
|
-
RB2 -.-> HKDF2 --> F2([Return Secure Random Bytes])
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
F --> FIV(IV)
|
|
56
|
-
|
|
57
|
-
F2 --> DERIVEDEK[Securely derive DEK using Argon2 + Salt]
|
|
58
|
-
DERIVEDEK --> EK1(ENCRYPTION_KEY)
|
|
59
|
-
IK --> DERIVEDEK
|
|
60
|
-
|
|
61
|
-
FIV ==> FED([Encrypt DATA using AES-256-GCM with ENCRYPTION_KEY + IV])
|
|
62
|
-
EK1 ==> FED
|
|
63
|
-
ID ==> FED
|
|
64
|
-
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
FED -.- FFED["Encrypted data [IV + Salt + AuthTag + CipherText]"]
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
%% Style definitions
|
|
71
|
-
style ID fill:#BCD3A3,stroke:#333,stroke-width:2px;
|
|
72
|
-
style FIV fill:#ffcc00,stroke:#333,stroke-width:2px;
|
|
73
|
-
style EK1 fill:#66ff66,stroke:#333,stroke-width:2px;
|
|
74
|
-
style FED fill:#cc99ff,stroke:#333,stroke-width:2px;
|
|
75
|
-
style FFED fill:#ff9966,stroke:#333,stroke-width:2px;
|
|
76
|
-
|
|
77
|
-
style CRB fill:#f9f,stroke:#333,stroke-width:2px
|
|
78
|
-
style CRB2 fill:#f9f,stroke:#333,stroke-width:2px
|
|
79
|
-
style SK fill:#bbf,stroke:#333,stroke-width:2px
|
|
80
|
-
style RB fill:#bbf,stroke:#333,stroke-width:2px
|
|
81
|
-
style HKDF fill:#bfb,stroke:#333,stroke-width:2px
|
|
82
|
-
style F fill:#00f0f0,stroke:#F0000,stroke-width:2px
|
|
83
|
-
|
|
84
|
-
style CRB23 fill:#f9f,stroke:#333,stroke-width:2px
|
|
85
|
-
style CRB22 fill:#f9f,stroke:#333,stroke-width:2px
|
|
86
|
-
style SK2 fill:#bbf,stroke:#333,stroke-width:2px
|
|
87
|
-
style RB2 fill:#bbf,stroke:#333,stroke-width:2px
|
|
88
|
-
style HKDF2 fill:#bfb,stroke:#333,stroke-width:2px
|
|
89
|
-
style F2 fill:#00f0f0,stroke:#F0000,stroke-width:2px
|
|
90
|
-
```
|
|
91
|
-
</div>
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
## **Explanation of the Diagram**
|
|
95
|
-
1) **Generate IV (12 bytes)**: A 12-byte IV is generated using `HKDF(sha3-256 + random_key + random_salt)`.
|
|
96
|
-
2) **Generate Salt (64 bytes)**: A 64-byte salt is generated, also using `HKDF(sha3-256 + random_key + random_salt)`.
|
|
97
|
-
3) **Derive Secure Encryption Key**: A secure encryption key is derived using **Argon2** with the _Key_ and **Salt**.
|
|
98
|
-
4) **Encrypt Data**: The _input data_ is encrypted using **AES-256-GCM** with the derived secure encryption key,
|
|
99
|
-
producing the encrypted result in format: `[IV + Salt + AuthTag + CipherText]`.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
[1]: ../guides/symmetric-encryption#symmetricdataencrypt
|
|
103
|
-
[2]: ../api-reference/settings#masterkey-1
|