@futdevpro/fsm-dynamo 1.10.50 → 1.10.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Error codes for crypto operations
3
+ */
4
+ /**
5
+ * Configuration options for encryption/decryption
6
+ */
7
+ export interface CryptoConfig {
8
+ ivLength?: number;
9
+ saltLength?: number;
10
+ keyIterations?: number;
11
+ keySize?: number;
12
+ }
13
+ /**
14
+ * A utility class for secure encryption and decryption of data
15
+ * Uses AES-256-CBC with PBKDF2 key derivation
16
+ */
17
+ export declare class DyFM_Crypto {
18
+ private static readonly DEFAULT_CONFIG;
19
+ private static readonly defaultErrorUserMsg;
20
+ /**
21
+ * Validates the input data and key
22
+ * @throws {DyFM_Error} if validation fails
23
+ */
24
+ private static validateInput;
25
+ /**
26
+ * Generates a deterministic IV based on the input data and key
27
+ */
28
+ private static generateIV;
29
+ /**
30
+ * Generates a deterministic salt based on the input data and key
31
+ */
32
+ private static generateSalt;
33
+ /**
34
+ * Derives a key using PBKDF2
35
+ */
36
+ private static deriveKey;
37
+ /**
38
+ * Safely serializes data to JSON
39
+ */
40
+ private static safeSerialize;
41
+ /**
42
+ * Safely deserializes JSON data
43
+ */
44
+ private static safeDeserialize;
45
+ /**
46
+ * Encrypts data using AES-256-CBC
47
+ * @param data The data to encrypt
48
+ * @param key The encryption key
49
+ * @param config Optional configuration
50
+ * @returns URL-safe encrypted string
51
+ * @throws {DyFM_Error} if encryption fails
52
+ */
53
+ static encrypt<T>(data: T, key: string, config?: CryptoConfig): string;
54
+ /**
55
+ * Decrypts data that was encrypted using encrypt()
56
+ * @param encryptedData The encrypted data
57
+ * @param key The decryption key
58
+ * @param config Optional configuration
59
+ * @returns The decrypted data
60
+ * @throws {DyFM_Error} if decryption fails
61
+ */
62
+ static decrypt<T>(encryptedData: string, key: string, config?: CryptoConfig): T;
63
+ /**
64
+ * Generates a secure random key
65
+ * @param length Length of the key in bytes (default: 32)
66
+ * @returns A secure random key
67
+ */
68
+ static generateKey(length?: number): string;
69
+ /**
70
+ * Validates if a string is a valid encrypted data
71
+ * @param encryptedData The data to validate
72
+ * @returns true if the data appears to be valid encrypted data
73
+ */
74
+ static isValidEncryptedData(encryptedData: string): boolean;
75
+ /**
76
+ * Gets default error settings
77
+ */
78
+ private static getDefaultErrorSettings;
79
+ }
80
+ //# sourceMappingURL=crypto-non-stable.util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto-non-stable.util.d.ts","sourceRoot":"","sources":["../../../../src/_modules/crypto/_collections/crypto-non-stable.util.ts"],"names":[],"mappings":"AAOA;;GAEG;AASH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAKpC;IACF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAEY;IAMvD;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAkB5B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,UAAU;IAKzB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAK3B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IAOxB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAY5B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IA6B9B;;;;;;;OAOG;IACH,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM;IAsCtE;;;;;;;OAOG;IACH,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,CAAC;IAwD/E;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,MAAM,GAAE,MAAW,GAAG,MAAM;IAI/C;;;;OAIG;IACH,MAAM,CAAC,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO;IAO3D;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,uBAAuB;CAQvC"}
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyFM_Crypto = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const CryptoJS = tslib_1.__importStar(require("crypto-js"));
6
+ const error_control_model_1 = require("../../../_models/control-models/error.control-model");
7
+ /**
8
+ * A utility class for secure encryption and decryption of data
9
+ * Uses AES-256-CBC with PBKDF2 key derivation
10
+ */
11
+ class DyFM_Crypto {
12
+ static DEFAULT_CONFIG = {
13
+ ivLength: 16, // 128 bits
14
+ saltLength: 16, // 128 bits
15
+ keyIterations: 10000,
16
+ keySize: 8 // 256 bits (8 * 32)
17
+ };
18
+ static defaultErrorUserMsg = `We encountered an unhandled Authentication Error, ` +
19
+ `\nplease contact the responsible development team.`;
20
+ // Tömör: kb. 60–80 karakteres token, nem 200+
21
+ // Nem szabványos: nehéz visszafejteni
22
+ // Használható cookie, header, URL-ben
23
+ /**
24
+ * Validates the input data and key
25
+ * @throws {DyFM_Error} if validation fails
26
+ */
27
+ static validateInput(data, key) {
28
+ if (!key || typeof key !== 'string' || key.trim().length === 0) {
29
+ throw new error_control_model_1.DyFM_Error({
30
+ ...this.getDefaultErrorSettings('validateInput'),
31
+ errorCode: 'DyFM-CRY-IKY',
32
+ message: 'Invalid encryption key'
33
+ });
34
+ }
35
+ if (data === undefined || data === null) {
36
+ throw new error_control_model_1.DyFM_Error({
37
+ ...this.getDefaultErrorSettings('validateInput'),
38
+ errorCode: 'DyFM-CRY-IDT',
39
+ message: 'Invalid data to encrypt/decrypt'
40
+ });
41
+ }
42
+ }
43
+ /**
44
+ * Generates a deterministic IV based on the input data and key
45
+ */
46
+ static generateIV(data, key, config) {
47
+ const hash = CryptoJS.SHA256(data + key);
48
+ return CryptoJS.lib.WordArray.create(hash.words.slice(0, config.ivLength / 4));
49
+ }
50
+ /**
51
+ * Generates a deterministic salt based on the input data and key
52
+ */
53
+ static generateSalt(data, key, config) {
54
+ const hash = CryptoJS.SHA256(key + data);
55
+ return CryptoJS.lib.WordArray.create(hash.words.slice(0, config.saltLength / 4));
56
+ }
57
+ /**
58
+ * Derives a key using PBKDF2
59
+ */
60
+ static deriveKey(key, salt, config) {
61
+ return CryptoJS.PBKDF2(key, salt, {
62
+ keySize: config.keySize,
63
+ iterations: config.keyIterations
64
+ });
65
+ }
66
+ /**
67
+ * Safely serializes data to JSON
68
+ */
69
+ static safeSerialize(data) {
70
+ try {
71
+ return JSON.stringify(data);
72
+ }
73
+ catch (error) {
74
+ throw new error_control_model_1.DyFM_Error({
75
+ ...this.getDefaultErrorSettings('safeSerialize', error),
76
+ errorCode: 'DyFM-CRY-SER',
77
+ message: 'Failed to serialize data'
78
+ });
79
+ }
80
+ }
81
+ /**
82
+ * Safely deserializes JSON data
83
+ */
84
+ static safeDeserialize(data) {
85
+ try {
86
+ let parsed = JSON.parse(data);
87
+ // Handle double-stringified JSON
88
+ if (typeof parsed === 'string') {
89
+ try {
90
+ parsed = JSON.parse(parsed);
91
+ }
92
+ catch {
93
+ // If second parse fails, return the string as is
94
+ return parsed;
95
+ }
96
+ }
97
+ // Handle primitive values
98
+ if (typeof parsed === 'string' || typeof parsed === 'number' || typeof parsed === 'boolean') {
99
+ return parsed;
100
+ }
101
+ return parsed;
102
+ }
103
+ catch (error) {
104
+ throw new error_control_model_1.DyFM_Error({
105
+ ...this.getDefaultErrorSettings('safeDeserialize', error),
106
+ errorCode: 'DyFM-CRY-DES',
107
+ message: 'Failed to deserialize data'
108
+ });
109
+ }
110
+ }
111
+ /**
112
+ * Encrypts data using AES-256-CBC
113
+ * @param data The data to encrypt
114
+ * @param key The encryption key
115
+ * @param config Optional configuration
116
+ * @returns URL-safe encrypted string
117
+ * @throws {DyFM_Error} if encryption fails
118
+ */
119
+ static encrypt(data, key, config) {
120
+ try {
121
+ this.validateInput(data, key);
122
+ const finalConfig = { ...this.DEFAULT_CONFIG, ...config };
123
+ // Convert data to string
124
+ const dataStr = this.safeSerialize(data);
125
+ // Generate deterministic IV and salt based on data and key
126
+ const iv = this.generateIV(dataStr, key, finalConfig);
127
+ const salt = this.generateSalt(dataStr, key, finalConfig);
128
+ // Derive key using PBKDF2
129
+ const derivedKey = this.deriveKey(key, salt, finalConfig);
130
+ // Encrypt the data
131
+ const encrypted = CryptoJS.AES.encrypt(dataStr, derivedKey, {
132
+ iv: iv,
133
+ mode: CryptoJS.mode.CBC,
134
+ padding: CryptoJS.pad.Pkcs7
135
+ });
136
+ // Combine IV + Salt + Ciphertext
137
+ const combined = iv.concat(salt).concat(encrypted.ciphertext);
138
+ // Convert to URL-safe base64
139
+ return CryptoJS.enc.Base64.stringify(combined)
140
+ .replace(/\+/g, '-')
141
+ .replace(/\//g, '_')
142
+ .replace(/=+$/, '');
143
+ }
144
+ catch (error) {
145
+ throw new error_control_model_1.DyFM_Error({
146
+ ...this.getDefaultErrorSettings('encrypt', error),
147
+ errorCode: 'DyFM-CRY-ENC',
148
+ });
149
+ }
150
+ }
151
+ /**
152
+ * Decrypts data that was encrypted using encrypt()
153
+ * @param encryptedData The encrypted data
154
+ * @param key The decryption key
155
+ * @param config Optional configuration
156
+ * @returns The decrypted data
157
+ * @throws {DyFM_Error} if decryption fails
158
+ */
159
+ static decrypt(encryptedData, key, config) {
160
+ try {
161
+ this.validateInput(encryptedData, key);
162
+ const finalConfig = { ...this.DEFAULT_CONFIG, ...config };
163
+ // Convert from URL-safe base64
164
+ const base64 = encryptedData
165
+ .replace(/-/g, '+')
166
+ .replace(/_/g, '/');
167
+ // Parse the combined data
168
+ const combined = CryptoJS.enc.Base64.parse(base64);
169
+ // Validate minimum length (IV + Salt + minimum ciphertext)
170
+ const minLength = (finalConfig.ivLength + finalConfig.saltLength + 16) / 4; // 16 bytes minimum for ciphertext
171
+ if (combined.words.length < minLength) {
172
+ throw new Error('Invalid encrypted data length');
173
+ }
174
+ // Extract IV, salt, and ciphertext
175
+ const iv = CryptoJS.lib.WordArray.create(combined.words.slice(0, finalConfig.ivLength / 4));
176
+ const salt = CryptoJS.lib.WordArray.create(combined.words.slice(finalConfig.ivLength / 4, (finalConfig.ivLength + finalConfig.saltLength) / 4));
177
+ const ciphertext = CryptoJS.lib.WordArray.create(combined.words.slice((finalConfig.ivLength + finalConfig.saltLength) / 4));
178
+ // Derive key using PBKDF2
179
+ const derivedKey = this.deriveKey(key, salt, finalConfig);
180
+ // Decrypt the data
181
+ const decrypted = CryptoJS.AES.decrypt({ ciphertext: ciphertext }, derivedKey, {
182
+ iv: iv,
183
+ mode: CryptoJS.mode.CBC,
184
+ padding: CryptoJS.pad.Pkcs7
185
+ });
186
+ // Parse JSON
187
+ const decryptedStr = decrypted.toString(CryptoJS.enc.Utf8);
188
+ return this.safeDeserialize(decryptedStr);
189
+ }
190
+ catch (error) {
191
+ throw new error_control_model_1.DyFM_Error({
192
+ ...this.getDefaultErrorSettings('decrypt', error),
193
+ errorCode: 'DyFM-CRY-DRY',
194
+ });
195
+ }
196
+ }
197
+ /**
198
+ * Generates a secure random key
199
+ * @param length Length of the key in bytes (default: 32)
200
+ * @returns A secure random key
201
+ */
202
+ static generateKey(length = 32) {
203
+ return CryptoJS.lib.WordArray.random(length).toString();
204
+ }
205
+ /**
206
+ * Validates if a string is a valid encrypted data
207
+ * @param encryptedData The data to validate
208
+ * @returns true if the data appears to be valid encrypted data
209
+ */
210
+ static isValidEncryptedData(encryptedData) {
211
+ if (!encryptedData || typeof encryptedData !== 'string') {
212
+ return false;
213
+ }
214
+ return /^[A-Za-z0-9\-_]+$/.test(encryptedData);
215
+ }
216
+ /**
217
+ * Gets default error settings
218
+ */
219
+ static getDefaultErrorSettings(operation, error) {
220
+ return {
221
+ status: error?.___status ?? error?.status ?? 401,
222
+ message: `Crypto operation "${operation}" failed`,
223
+ error: error,
224
+ errorCode: 'DyFM-CRY-ERR'
225
+ };
226
+ }
227
+ }
228
+ exports.DyFM_Crypto = DyFM_Crypto;
229
+ //# sourceMappingURL=crypto-non-stable.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto-non-stable.util.js","sourceRoot":"","sources":["../../../../src/_modules/crypto/_collections/crypto-non-stable.util.ts"],"names":[],"mappings":"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"}
@@ -1,77 +1,45 @@
1
- /**
2
- * Error codes for crypto operations
3
- */
4
- /**
5
- * Configuration options for encryption/decryption
6
- */
7
- export interface CryptoConfig {
8
- ivLength?: number;
9
- saltLength?: number;
10
- keyIterations?: number;
11
- keySize?: number;
12
- }
13
1
  /**
14
2
  * A utility class for secure encryption and decryption of data
15
- * Uses AES-256-CBC with PBKDF2 key derivation
3
+ * Uses AES-256-CBC with deterministic IV and salt for consistent results
16
4
  */
17
5
  export declare class DyFM_Crypto {
18
- private static readonly DEFAULT_CONFIG;
19
6
  private static readonly defaultErrorUserMsg;
20
7
  /**
21
- * Validates the input data and key
22
- * @throws {DyFM_Error} if validation fails
8
+ * Validates the encryption key
23
9
  */
24
- private static validateInput;
10
+ private static validateKey;
25
11
  /**
26
- * Generates a deterministic IV based on the input data and key
12
+ * Safely serializes data to JSON
27
13
  */
28
- private static generateIV;
14
+ private static safeSerialize;
29
15
  /**
30
- * Generates a deterministic salt based on the input data and key
16
+ * Safely deserializes JSON data
31
17
  */
32
- private static generateSalt;
18
+ private static safeDeserialize;
33
19
  /**
34
- * Derives a key using PBKDF2
20
+ * Derives a 256-bit key from the passphrase using SHA256
35
21
  */
36
22
  private static deriveKey;
37
23
  /**
38
- * Safely serializes data to JSON
24
+ * Creates a deterministic IV from the key only
39
25
  */
40
- private static safeSerialize;
41
- /**
42
- * Safely deserializes JSON data
43
- */
44
- private static safeDeserialize;
26
+ private static createDeterministicIV;
45
27
  /**
46
- * Encrypts data using AES-256-CBC
28
+ * Encrypts data using AES-256-CBC with deterministic key and IV
47
29
  * @param data The data to encrypt
48
30
  * @param key The encryption key
49
- * @param config Optional configuration
50
31
  * @returns URL-safe encrypted string
51
32
  * @throws {DyFM_Error} if encryption fails
52
33
  */
53
- static encrypt<T>(data: T, key: string, config?: CryptoConfig): string;
34
+ static encrypt<T>(data: T, key: string): string;
54
35
  /**
55
36
  * Decrypts data that was encrypted using encrypt()
56
37
  * @param encryptedData The encrypted data
57
38
  * @param key The decryption key
58
- * @param config Optional configuration
59
39
  * @returns The decrypted data
60
40
  * @throws {DyFM_Error} if decryption fails
61
41
  */
62
- static decrypt<T>(encryptedData: string, key: string, config?: CryptoConfig): T;
63
- /**
64
- * Generates a secure random key
65
- * @param length Length of the key in bytes (default: 32)
66
- * @returns A secure random key
67
- */
68
- static generateKey(length?: number): string;
69
- /**
70
- * Validates if a string is a valid encrypted data
71
- * @param encryptedData The data to validate
72
- * @returns true if the data appears to be valid encrypted data
73
- */
74
- static isValidEncryptedData(encryptedData: string): boolean;
42
+ static decrypt<T>(encryptedData: string, key: string): T;
75
43
  /**
76
44
  * Gets default error settings
77
45
  */
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.util.d.ts","sourceRoot":"","sources":["../../../../src/_modules/crypto/_collections/crypto.util.ts"],"names":[],"mappings":"AAOA;;GAEG;AASH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAKpC;IACF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAEY;IAMvD;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAkB5B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,UAAU;IAKzB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAK3B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IAOxB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAY5B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IA6B9B;;;;;;;OAOG;IACH,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM;IAsCtE;;;;;;;OAOG;IACH,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,CAAC;IAwD/E;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,MAAM,GAAE,MAAW,GAAG,MAAM;IAI/C;;;;OAIG;IACH,MAAM,CAAC,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO;IAO3D;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,uBAAuB;CAQvC"}
1
+ {"version":3,"file":"crypto.util.d.ts","sourceRoot":"","sources":["../../../../src/_modules/crypto/_collections/crypto.util.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAEY;IAEvD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAkB1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAY5B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IA6B9B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IAIxB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAKpC;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IA0C/C;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC;IAyDxD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,uBAAuB;CAQvC"}
@@ -6,63 +6,30 @@ const CryptoJS = tslib_1.__importStar(require("crypto-js"));
6
6
  const error_control_model_1 = require("../../../_models/control-models/error.control-model");
7
7
  /**
8
8
  * A utility class for secure encryption and decryption of data
9
- * Uses AES-256-CBC with PBKDF2 key derivation
9
+ * Uses AES-256-CBC with deterministic IV and salt for consistent results
10
10
  */
11
11
  class DyFM_Crypto {
12
- static DEFAULT_CONFIG = {
13
- ivLength: 16, // 128 bits
14
- saltLength: 16, // 128 bits
15
- keyIterations: 10000,
16
- keySize: 8 // 256 bits (8 * 32)
17
- };
18
12
  static defaultErrorUserMsg = `We encountered an unhandled Authentication Error, ` +
19
13
  `\nplease contact the responsible development team.`;
20
- // Tömör: kb. 60–80 karakteres token, nem 200+
21
- // Nem szabványos: nehéz visszafejteni
22
- // Használható cookie, header, URL-ben
23
14
  /**
24
- * Validates the input data and key
25
- * @throws {DyFM_Error} if validation fails
15
+ * Validates the encryption key
26
16
  */
27
- static validateInput(data, key) {
28
- if (!key || typeof key !== 'string' || key.trim().length === 0) {
17
+ static validateKey(key) {
18
+ if (!key || typeof key !== 'string') {
29
19
  throw new error_control_model_1.DyFM_Error({
30
- ...this.getDefaultErrorSettings('validateInput'),
31
- errorCode: 'DyFM-CRY-IKY',
32
- message: 'Invalid encryption key'
20
+ status: 401,
21
+ message: 'Encryption key is required and must be a string',
22
+ errorCode: 'DyFM-CRY-KEY-REQ'
33
23
  });
34
24
  }
35
- if (data === undefined || data === null) {
25
+ if (key.trim().length === 0) {
36
26
  throw new error_control_model_1.DyFM_Error({
37
- ...this.getDefaultErrorSettings('validateInput'),
38
- errorCode: 'DyFM-CRY-IDT',
39
- message: 'Invalid data to encrypt/decrypt'
27
+ status: 401,
28
+ message: 'Encryption key cannot be empty or whitespace-only',
29
+ errorCode: 'DyFM-CRY-KEY-EMPTY'
40
30
  });
41
31
  }
42
32
  }
43
- /**
44
- * Generates a deterministic IV based on the input data and key
45
- */
46
- static generateIV(data, key, config) {
47
- const hash = CryptoJS.SHA256(data + key);
48
- return CryptoJS.lib.WordArray.create(hash.words.slice(0, config.ivLength / 4));
49
- }
50
- /**
51
- * Generates a deterministic salt based on the input data and key
52
- */
53
- static generateSalt(data, key, config) {
54
- const hash = CryptoJS.SHA256(key + data);
55
- return CryptoJS.lib.WordArray.create(hash.words.slice(0, config.saltLength / 4));
56
- }
57
- /**
58
- * Derives a key using PBKDF2
59
- */
60
- static deriveKey(key, salt, config) {
61
- return CryptoJS.PBKDF2(key, salt, {
62
- keySize: config.keySize,
63
- iterations: config.keyIterations
64
- });
65
- }
66
33
  /**
67
34
  * Safely serializes data to JSON
68
35
  */
@@ -109,34 +76,51 @@ class DyFM_Crypto {
109
76
  }
110
77
  }
111
78
  /**
112
- * Encrypts data using AES-256-CBC
79
+ * Derives a 256-bit key from the passphrase using SHA256
80
+ */
81
+ static deriveKey(key) {
82
+ return CryptoJS.SHA256(key);
83
+ }
84
+ /**
85
+ * Creates a deterministic IV from the key only
86
+ */
87
+ static createDeterministicIV(key) {
88
+ const hash = CryptoJS.SHA256(key + ':iv');
89
+ return CryptoJS.lib.WordArray.create(hash.words.slice(0, 4)); // Use first 16 bytes (128 bits)
90
+ }
91
+ /**
92
+ * Encrypts data using AES-256-CBC with deterministic key and IV
113
93
  * @param data The data to encrypt
114
94
  * @param key The encryption key
115
- * @param config Optional configuration
116
95
  * @returns URL-safe encrypted string
117
96
  * @throws {DyFM_Error} if encryption fails
118
97
  */
119
- static encrypt(data, key, config) {
98
+ static encrypt(data, key) {
120
99
  try {
121
- this.validateInput(data, key);
122
- const finalConfig = { ...this.DEFAULT_CONFIG, ...config };
100
+ // Validate key
101
+ this.validateKey(key);
102
+ // Validate data
103
+ if (data === undefined || data === null) {
104
+ throw new error_control_model_1.DyFM_Error({
105
+ status: 401,
106
+ message: 'Data cannot be undefined or null',
107
+ errorCode: 'DyFM-CRY-DATA-NULL'
108
+ });
109
+ }
123
110
  // Convert data to string
124
111
  const dataStr = this.safeSerialize(data);
125
- // Generate deterministic IV and salt based on data and key
126
- const iv = this.generateIV(dataStr, key, finalConfig);
127
- const salt = this.generateSalt(dataStr, key, finalConfig);
128
- // Derive key using PBKDF2
129
- const derivedKey = this.deriveKey(key, salt, finalConfig);
130
- // Encrypt the data
131
- const encrypted = CryptoJS.AES.encrypt(dataStr, derivedKey, {
112
+ // Derive key and IV
113
+ const aesKey = this.deriveKey(key);
114
+ const iv = this.createDeterministicIV(key);
115
+ // Encrypt the data with deterministic key and IV
116
+ const encrypted = CryptoJS.AES.encrypt(dataStr, aesKey, {
132
117
  iv: iv,
133
118
  mode: CryptoJS.mode.CBC,
134
119
  padding: CryptoJS.pad.Pkcs7
135
120
  });
136
- // Combine IV + Salt + Ciphertext
137
- const combined = iv.concat(salt).concat(encrypted.ciphertext);
138
121
  // Convert to URL-safe base64
139
- return CryptoJS.enc.Base64.stringify(combined)
122
+ const base64 = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
123
+ return base64
140
124
  .replace(/\+/g, '-')
141
125
  .replace(/\//g, '_')
142
126
  .replace(/=+$/, '');
@@ -152,39 +136,49 @@ class DyFM_Crypto {
152
136
  * Decrypts data that was encrypted using encrypt()
153
137
  * @param encryptedData The encrypted data
154
138
  * @param key The decryption key
155
- * @param config Optional configuration
156
139
  * @returns The decrypted data
157
140
  * @throws {DyFM_Error} if decryption fails
158
141
  */
159
- static decrypt(encryptedData, key, config) {
142
+ static decrypt(encryptedData, key) {
160
143
  try {
161
- this.validateInput(encryptedData, key);
162
- const finalConfig = { ...this.DEFAULT_CONFIG, ...config };
144
+ // Validate key
145
+ this.validateKey(key);
146
+ // Validate encrypted data
147
+ if (!encryptedData || typeof encryptedData !== 'string') {
148
+ throw new error_control_model_1.DyFM_Error({
149
+ status: 401,
150
+ message: 'Encrypted data is required and must be a string',
151
+ errorCode: 'DyFM-CRY-DATA-REQ'
152
+ });
153
+ }
163
154
  // Convert from URL-safe base64
164
- const base64 = encryptedData
155
+ let base64 = encryptedData
165
156
  .replace(/-/g, '+')
166
157
  .replace(/_/g, '/');
167
- // Parse the combined data
168
- const combined = CryptoJS.enc.Base64.parse(base64);
169
- // Validate minimum length (IV + Salt + minimum ciphertext)
170
- const minLength = (finalConfig.ivLength + finalConfig.saltLength + 16) / 4; // 16 bytes minimum for ciphertext
171
- if (combined.words.length < minLength) {
172
- throw new Error('Invalid encrypted data length');
158
+ // Add padding if needed
159
+ const padLength = 4 - (base64.length % 4);
160
+ if (padLength < 4) {
161
+ base64 += '='.repeat(padLength);
173
162
  }
174
- // Extract IV, salt, and ciphertext
175
- const iv = CryptoJS.lib.WordArray.create(combined.words.slice(0, finalConfig.ivLength / 4));
176
- const salt = CryptoJS.lib.WordArray.create(combined.words.slice(finalConfig.ivLength / 4, (finalConfig.ivLength + finalConfig.saltLength) / 4));
177
- const ciphertext = CryptoJS.lib.WordArray.create(combined.words.slice((finalConfig.ivLength + finalConfig.saltLength) / 4));
178
- // Derive key using PBKDF2
179
- const derivedKey = this.deriveKey(key, salt, finalConfig);
163
+ // Derive key and IV
164
+ const aesKey = this.deriveKey(key);
165
+ const iv = this.createDeterministicIV(key);
180
166
  // Decrypt the data
181
- const decrypted = CryptoJS.AES.decrypt({ ciphertext: ciphertext }, derivedKey, {
167
+ const encryptedWA = CryptoJS.enc.Base64.parse(base64);
168
+ const decrypted = CryptoJS.AES.decrypt({ ciphertext: encryptedWA }, aesKey, {
182
169
  iv: iv,
183
170
  mode: CryptoJS.mode.CBC,
184
171
  padding: CryptoJS.pad.Pkcs7
185
172
  });
186
173
  // Parse JSON
187
174
  const decryptedStr = decrypted.toString(CryptoJS.enc.Utf8);
175
+ if (!decryptedStr) {
176
+ throw new error_control_model_1.DyFM_Error({
177
+ status: 401,
178
+ message: 'Failed to decrypt data - invalid key or corrupted data',
179
+ errorCode: 'DyFM-CRY-DEC-FAIL'
180
+ });
181
+ }
188
182
  return this.safeDeserialize(decryptedStr);
189
183
  }
190
184
  catch (error) {
@@ -194,25 +188,6 @@ class DyFM_Crypto {
194
188
  });
195
189
  }
196
190
  }
197
- /**
198
- * Generates a secure random key
199
- * @param length Length of the key in bytes (default: 32)
200
- * @returns A secure random key
201
- */
202
- static generateKey(length = 32) {
203
- return CryptoJS.lib.WordArray.random(length).toString();
204
- }
205
- /**
206
- * Validates if a string is a valid encrypted data
207
- * @param encryptedData The data to validate
208
- * @returns true if the data appears to be valid encrypted data
209
- */
210
- static isValidEncryptedData(encryptedData) {
211
- if (!encryptedData || typeof encryptedData !== 'string') {
212
- return false;
213
- }
214
- return /^[A-Za-z0-9\-_]+$/.test(encryptedData);
215
- }
216
191
  /**
217
192
  * Gets default error settings
218
193
  */