@futdevpro/fsm-dynamo 1.14.20 → 1.14.22
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/build/_modules/crypto/_collections/crypto.util.d.ts.map +1 -1
- package/build/_modules/crypto/_collections/crypto.util.edge.spec.d.ts +2 -0
- package/build/_modules/crypto/_collections/crypto.util.edge.spec.d.ts.map +1 -0
- package/build/_modules/crypto/_collections/crypto.util.edge.spec.js +551 -0
- package/build/_modules/crypto/_collections/crypto.util.edge.spec.js.map +1 -0
- package/build/_modules/crypto/_collections/crypto.util.extra.spec.d.ts +2 -0
- package/build/_modules/crypto/_collections/crypto.util.extra.spec.d.ts.map +1 -0
- package/build/_modules/crypto/_collections/crypto.util.extra.spec.js +555 -0
- package/build/_modules/crypto/_collections/crypto.util.extra.spec.js.map +1 -0
- package/build/_modules/crypto/_collections/crypto.util.js +42 -3
- package/build/_modules/crypto/_collections/crypto.util.js.map +1 -1
- package/build/_modules/crypto/_collections/crypto.util.simple.spec.d.ts +2 -0
- package/build/_modules/crypto/_collections/crypto.util.simple.spec.d.ts.map +1 -0
- package/build/_modules/crypto/_collections/crypto.util.simple.spec.js +429 -0
- package/build/_modules/crypto/_collections/crypto.util.simple.spec.js.map +1 -0
- package/futdevpro-fsm-dynamo-01.14.22.tgz +0 -0
- package/package.json +2 -2
- package/src/_modules/crypto/_collections/crypto.util.edge.spec.ts +606 -0
- package/src/_modules/crypto/_collections/crypto.util.extra.spec.ts +643 -0
- package/src/_modules/crypto/_collections/crypto.util.simple.spec.ts +513 -0
- package/src/_modules/crypto/_collections/crypto.util.ts +93 -48
- package/build/_modules/crypto/_collections/crypto.util.spec.d.ts +0 -2
- package/build/_modules/crypto/_collections/crypto.util.spec.d.ts.map +0 -1
- package/build/_modules/crypto/_collections/crypto.util.spec.js +0 -1180
- package/build/_modules/crypto/_collections/crypto.util.spec.js.map +0 -1
- package/futdevpro-fsm-dynamo-01.14.20.tgz +0 -0
- package/src/_modules/crypto/_collections/crypto.util.spec.ts +0 -1370
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
DyFM_Error_Settings
|
|
5
5
|
} from '../../../_models/control-models/error.control-model';
|
|
6
6
|
import { DyFM_Object } from '../../../_collections/utils/object.util';
|
|
7
|
+
import { DyFM_global_settings } from '../../../_collections/constants/global-settings.const';
|
|
8
|
+
import { DyFM_Log } from '../../../_collections/utils/log.util';
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
/**
|
|
@@ -35,14 +37,14 @@ export interface CryptoConfig {
|
|
|
35
37
|
* systems is more important than cryptographic security.
|
|
36
38
|
*/
|
|
37
39
|
export class DyFM_Crypto {
|
|
38
|
-
private static readonly CRYPTO_VERSION = '1.0';
|
|
40
|
+
private static readonly CRYPTO_VERSION: string = '1.0';
|
|
39
41
|
private static readonly DEFAULT_CONFIG: Required<CryptoConfig> = {
|
|
40
42
|
ivLength: 16, // 128 bits
|
|
41
43
|
saltLength: 16, // 128 bits
|
|
42
44
|
keyIterations: 1000, // Reduced for better performance and stability
|
|
43
45
|
keySize: 8 // 256 bits (8 * 32)
|
|
44
46
|
};
|
|
45
|
-
private static readonly defaultErrorUserMsg =
|
|
47
|
+
private static readonly defaultErrorUserMsg: string =
|
|
46
48
|
`We encountered an unhandled Authentication Error, ` +
|
|
47
49
|
`\nplease contact the responsible development team.`;
|
|
48
50
|
|
|
@@ -185,14 +187,14 @@ export class DyFM_Crypto {
|
|
|
185
187
|
*/
|
|
186
188
|
private static generateIV(data: string, key: string, config: Required<CryptoConfig>): CryptoJS.lib.WordArray {
|
|
187
189
|
// Create a deterministic seed from data and key
|
|
188
|
-
const seed = this.createDeterministicSeed(data, key, 'IV');
|
|
190
|
+
const seed: string = this.createDeterministicSeed(data, key, 'IV');
|
|
189
191
|
|
|
190
192
|
// Use SHA-256 for better stability and consistency
|
|
191
|
-
const hash = CryptoJS.SHA256(seed);
|
|
193
|
+
const hash: CryptoJS.lib.WordArray = CryptoJS.SHA256(seed);
|
|
192
194
|
|
|
193
195
|
// Extract exactly 16 bytes (128 bits) for IV
|
|
194
196
|
// Use the first 4 words (4 * 4 = 16 bytes) from the hash
|
|
195
|
-
const ivWords = hash.words.slice(0, 4);
|
|
197
|
+
const ivWords: number[] = hash.words.slice(0, 4);
|
|
196
198
|
return CryptoJS.lib.WordArray.create(ivWords);
|
|
197
199
|
}
|
|
198
200
|
|
|
@@ -205,14 +207,14 @@ export class DyFM_Crypto {
|
|
|
205
207
|
*/
|
|
206
208
|
private static generateSalt(data: string, key: string, config: Required<CryptoConfig>): CryptoJS.lib.WordArray {
|
|
207
209
|
// Create a deterministic seed from data and key (different from IV)
|
|
208
|
-
const seed = this.createDeterministicSeed(data, key, 'SALT');
|
|
210
|
+
const seed: string = this.createDeterministicSeed(data, key, 'SALT');
|
|
209
211
|
|
|
210
212
|
// Use SHA-256 for better stability and consistency
|
|
211
|
-
const hash = CryptoJS.SHA256(seed);
|
|
213
|
+
const hash: CryptoJS.lib.WordArray = CryptoJS.SHA256(seed);
|
|
212
214
|
|
|
213
215
|
// Extract exactly 16 bytes (128 bits) for salt
|
|
214
216
|
// Use the first 4 words (4 * 4 = 16 bytes) from the hash
|
|
215
|
-
const saltWords = hash.words.slice(0, 4);
|
|
217
|
+
const saltWords: number[] = hash.words.slice(0, 4);
|
|
216
218
|
return CryptoJS.lib.WordArray.create(saltWords);
|
|
217
219
|
}
|
|
218
220
|
|
|
@@ -223,7 +225,7 @@ export class DyFM_Crypto {
|
|
|
223
225
|
private static createDeterministicSeed(data: string, key: string, purpose: string): string {
|
|
224
226
|
// Create a consistent seed that includes all relevant factors
|
|
225
227
|
// Order matters: data + key + purpose for consistency
|
|
226
|
-
const seed = `${data}|${key}|${purpose}`;
|
|
228
|
+
const seed: string = `${data}|${key}|${purpose}`;
|
|
227
229
|
return seed;
|
|
228
230
|
}
|
|
229
231
|
|
|
@@ -274,17 +276,17 @@ export class DyFM_Crypto {
|
|
|
274
276
|
if (typeof obj === 'object') {
|
|
275
277
|
// For objects, we need to be more careful about key ordering
|
|
276
278
|
// Use a stable sort that preserves original order when possible
|
|
277
|
-
const keys = Object.keys(obj);
|
|
279
|
+
const keys: string[] = Object.keys(obj);
|
|
278
280
|
|
|
279
281
|
// Only sort if there are potential ordering issues
|
|
280
|
-
const needsSorting = keys.some((key, index) => {
|
|
282
|
+
const needsSorting: boolean = keys.some((key, index) => {
|
|
281
283
|
if (index === 0) return false;
|
|
282
284
|
return key < keys[index - 1];
|
|
283
285
|
});
|
|
284
286
|
|
|
285
|
-
const sortedKeys = needsSorting ? [...keys].sort() : keys;
|
|
286
|
-
const pairs = sortedKeys.map(key => {
|
|
287
|
-
const value = this.deterministicStringify(obj[key]);
|
|
287
|
+
const sortedKeys: string[] = needsSorting ? [...keys].sort() : keys;
|
|
288
|
+
const pairs: string[] = sortedKeys.map(key => {
|
|
289
|
+
const value: string = this.deterministicStringify(obj[key]);
|
|
288
290
|
return JSON.stringify(key) + ':' + value;
|
|
289
291
|
});
|
|
290
292
|
return '{' + pairs.join(',') + '}';
|
|
@@ -313,14 +315,14 @@ export class DyFM_Crypto {
|
|
|
313
315
|
}
|
|
314
316
|
|
|
315
317
|
//let parsed = JSON.parse(data);
|
|
316
|
-
let parsed = DyFM_Object.failableSafeParseJSON(data);
|
|
318
|
+
let parsed: T = DyFM_Object.failableSafeParseJSON(data);
|
|
317
319
|
|
|
318
320
|
// Handle double-stringified JSON (or more levels of stringification)
|
|
319
|
-
let maxAttempts = 3; // Prevent infinite loops
|
|
321
|
+
let maxAttempts: number = 3; // Prevent infinite loops
|
|
320
322
|
while (typeof parsed === 'string' && maxAttempts > 0) {
|
|
321
323
|
try {
|
|
322
324
|
//const nextParsed = JSON.parse(parsed);
|
|
323
|
-
const nextParsed = DyFM_Object.failableSafeParseJSON(parsed);
|
|
325
|
+
const nextParsed: T = DyFM_Object.failableSafeParseJSON(parsed);
|
|
324
326
|
// Only continue if parsing actually changed the result
|
|
325
327
|
if (nextParsed !== parsed) {
|
|
326
328
|
parsed = nextParsed;
|
|
@@ -376,27 +378,27 @@ export class DyFM_Crypto {
|
|
|
376
378
|
static encrypt<T>(data: T, key: string, config?: CryptoConfig): string {
|
|
377
379
|
try {
|
|
378
380
|
this.validateInput(data, key, 'encrypt');
|
|
379
|
-
const finalConfig = { ...this.DEFAULT_CONFIG, ...config };
|
|
381
|
+
const finalConfig: Required<CryptoConfig> = { ...this.DEFAULT_CONFIG, ...config };
|
|
380
382
|
|
|
381
383
|
// Convert data to string
|
|
382
|
-
const dataStr = this.safeSerialize(data);
|
|
384
|
+
const dataStr: string = this.safeSerialize(data);
|
|
383
385
|
|
|
384
386
|
// Generate deterministic IV and salt based on data and key
|
|
385
|
-
const iv = this.generateIV(dataStr, key, finalConfig);
|
|
386
|
-
const salt = this.generateSalt(dataStr, key, finalConfig);
|
|
387
|
+
const iv: CryptoJS.lib.WordArray = this.generateIV(dataStr, key, finalConfig);
|
|
388
|
+
const salt: CryptoJS.lib.WordArray = this.generateSalt(dataStr, key, finalConfig);
|
|
387
389
|
|
|
388
390
|
// Derive key using PBKDF2
|
|
389
|
-
const derivedKey = this.deriveKey(key, salt, finalConfig);
|
|
391
|
+
const derivedKey: CryptoJS.lib.WordArray = this.deriveKey(key, salt, finalConfig);
|
|
390
392
|
|
|
391
393
|
// Encrypt the data
|
|
392
|
-
const encrypted = CryptoJS.AES.encrypt(dataStr, derivedKey, {
|
|
394
|
+
const encrypted: CryptoJS.lib.WordArray = CryptoJS.AES.encrypt(dataStr, derivedKey, {
|
|
393
395
|
iv: iv,
|
|
394
396
|
mode: CryptoJS.mode.CBC,
|
|
395
397
|
padding: CryptoJS.pad.Pkcs7
|
|
396
398
|
});
|
|
397
399
|
|
|
398
400
|
// Combine IV + Salt + Ciphertext (skip version for backward compatibility)
|
|
399
|
-
const combined = iv.concat(salt).concat(encrypted.ciphertext);
|
|
401
|
+
const combined: CryptoJS.lib.WordArray = iv.concat(salt).concat(encrypted.ciphertext);
|
|
400
402
|
|
|
401
403
|
// Convert to URL-safe base64
|
|
402
404
|
return CryptoJS.enc.Base64.stringify(combined)
|
|
@@ -422,43 +424,76 @@ export class DyFM_Crypto {
|
|
|
422
424
|
static decrypt<T>(encryptedData: string, key: string, config?: CryptoConfig): T {
|
|
423
425
|
try {
|
|
424
426
|
this.validateInput(encryptedData, key, 'decrypt');
|
|
425
|
-
const finalConfig = { ...this.DEFAULT_CONFIG, ...config };
|
|
427
|
+
const finalConfig: Required<CryptoConfig> = { ...this.DEFAULT_CONFIG, ...config };
|
|
426
428
|
|
|
427
429
|
// Convert from URL-safe base64
|
|
428
|
-
const base64 = encryptedData
|
|
430
|
+
const base64: string = encryptedData
|
|
429
431
|
.replace(/-/g, '+')
|
|
430
432
|
.replace(/_/g, '/');
|
|
431
433
|
|
|
434
|
+
// Add padding if needed (base64 must be multiple of 4 characters)
|
|
435
|
+
// This ensures CryptoJS.parse works correctly even when padding was stripped during URL transmission
|
|
436
|
+
const paddingNeeded: number = (4 - (base64.length % 4)) % 4;
|
|
437
|
+
const paddedBase64: string = base64 + '='.repeat(paddingNeeded);
|
|
438
|
+
|
|
439
|
+
// Validate base64 format before parsing
|
|
440
|
+
// Check if the string length makes sense for expected minimum byte count
|
|
441
|
+
// Minimum expected: 48 bytes = ~64 base64 characters (48 * 4/3 = 64)
|
|
442
|
+
const minExpectedBase64Length: number = Math.ceil((finalConfig.ivLength + finalConfig.saltLength + 16) * 4 / 3);
|
|
443
|
+
if (paddedBase64.length < minExpectedBase64Length) {
|
|
444
|
+
if (DyFM_global_settings.log_settings.server_debug) {
|
|
445
|
+
DyFM_Log.log(
|
|
446
|
+
`Encrypted data is too short. Expected at least ${minExpectedBase64Length} base64 characters ` +
|
|
447
|
+
`(for ${(finalConfig.ivLength + finalConfig.saltLength + 16)} bytes), ` +
|
|
448
|
+
`but received ${paddedBase64.length} characters (${encryptedData.length} original). ` +
|
|
449
|
+
`This may indicate the data was truncated during transmission or storage.` +
|
|
450
|
+
'\n\nEncrypted data: ' + encryptedData
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
throw new DyFM_Error({
|
|
455
|
+
...this.getDefaultErrorSettings('decrypt'),
|
|
456
|
+
errorCode: 'DyFM-CRY-DATA-CORRUPTED',
|
|
457
|
+
message: `Encrypted data is too short. Expected at least ${minExpectedBase64Length} base64 characters ` +
|
|
458
|
+
`(for ${(finalConfig.ivLength + finalConfig.saltLength + 16)} bytes), ` +
|
|
459
|
+
`but received ${paddedBase64.length} characters (${encryptedData.length} original). ` +
|
|
460
|
+
`This may indicate the data was truncated during transmission or storage.`
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
|
|
432
464
|
// Parse the combined data
|
|
433
|
-
const combined = CryptoJS.enc.Base64.parse(
|
|
465
|
+
const combined: CryptoJS.lib.WordArray = CryptoJS.enc.Base64.parse(paddedBase64);
|
|
434
466
|
|
|
435
467
|
// For now, skip version checking to maintain backward compatibility
|
|
436
468
|
// TODO: Implement proper version checking in future versions
|
|
437
469
|
|
|
438
470
|
// Validate minimum length (IV + Salt + minimum ciphertext)
|
|
439
|
-
const minLength = (finalConfig.ivLength + finalConfig.saltLength + 16) / 4; // 16 bytes minimum for ciphertext
|
|
471
|
+
const minLength: number = (finalConfig.ivLength + finalConfig.saltLength + 16) / 4; // 16 bytes minimum for ciphertext
|
|
440
472
|
if (combined.words.length < minLength) {
|
|
441
473
|
throw new DyFM_Error({
|
|
442
474
|
...this.getDefaultErrorSettings('decrypt'),
|
|
443
475
|
errorCode: 'DyFM-CRY-DATA-CORRUPTED',
|
|
444
|
-
message: `Encrypted data is corrupted or incomplete. Expected at least ${minLength * 4} bytes, but received ${combined.sigBytes} bytes
|
|
476
|
+
message: `Encrypted data is corrupted or incomplete. Expected at least ${minLength * 4} bytes, but received ${combined.sigBytes} bytes. ` +
|
|
477
|
+
`Original string length: ${encryptedData.length} characters. ` +
|
|
478
|
+
`Base64 length: ${base64.length} characters (${paddedBase64.length} with padding). ` +
|
|
479
|
+
`This may indicate the data was truncated during transmission or storage.`
|
|
445
480
|
});
|
|
446
481
|
}
|
|
447
482
|
|
|
448
483
|
// Extract IV, salt, and ciphertext (skip version for now)
|
|
449
|
-
const ivStart = 0;
|
|
450
|
-
const saltStart = ivStart + finalConfig.ivLength / 4;
|
|
451
|
-
const cipherStart = saltStart + finalConfig.saltLength / 4;
|
|
484
|
+
const ivStart: number = 0;
|
|
485
|
+
const saltStart: number = ivStart + finalConfig.ivLength / 4;
|
|
486
|
+
const cipherStart: number = saltStart + finalConfig.saltLength / 4;
|
|
452
487
|
|
|
453
|
-
const iv = CryptoJS.lib.WordArray.create(combined.words.slice(ivStart, saltStart));
|
|
454
|
-
const salt = CryptoJS.lib.WordArray.create(combined.words.slice(saltStart, cipherStart));
|
|
455
|
-
const ciphertext = CryptoJS.lib.WordArray.create(combined.words.slice(cipherStart));
|
|
488
|
+
const iv: CryptoJS.lib.WordArray = CryptoJS.lib.WordArray.create(combined.words.slice(ivStart, saltStart));
|
|
489
|
+
const salt: CryptoJS.lib.WordArray = CryptoJS.lib.WordArray.create(combined.words.slice(saltStart, cipherStart));
|
|
490
|
+
const ciphertext: CryptoJS.lib.WordArray = CryptoJS.lib.WordArray.create(combined.words.slice(cipherStart));
|
|
456
491
|
|
|
457
492
|
// Derive key using PBKDF2
|
|
458
|
-
const derivedKey = this.deriveKey(key, salt, finalConfig);
|
|
493
|
+
const derivedKey: CryptoJS.lib.WordArray = this.deriveKey(key, salt, finalConfig);
|
|
459
494
|
|
|
460
495
|
// Decrypt the data
|
|
461
|
-
const decrypted = CryptoJS.AES.decrypt(
|
|
496
|
+
const decrypted: CryptoJS.lib.WordArray = CryptoJS.AES.decrypt(
|
|
462
497
|
{ ciphertext: ciphertext },
|
|
463
498
|
derivedKey,
|
|
464
499
|
{
|
|
@@ -469,7 +504,7 @@ export class DyFM_Crypto {
|
|
|
469
504
|
);
|
|
470
505
|
|
|
471
506
|
// Parse JSON
|
|
472
|
-
const decryptedStr = decrypted.toString(CryptoJS.enc.Utf8);
|
|
507
|
+
const decryptedStr: string = decrypted.toString(CryptoJS.enc.Utf8);
|
|
473
508
|
|
|
474
509
|
// Check if decryption produced empty result
|
|
475
510
|
if (!decryptedStr || decryptedStr.trim().length === 0) {
|
|
@@ -522,15 +557,15 @@ export class DyFM_Crypto {
|
|
|
522
557
|
*/
|
|
523
558
|
static generateKey(length: number = 32, customChars?: string): string {
|
|
524
559
|
// Use custom character set if provided, otherwise use simple safe characters
|
|
525
|
-
const chars = customChars || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
526
|
-
let complexKey = '';
|
|
560
|
+
const chars: string = customChars || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
561
|
+
let complexKey: string = '';
|
|
527
562
|
|
|
528
563
|
// Generate random characters directly for the desired length
|
|
529
564
|
for (let i = 0; i < length; i++) {
|
|
530
565
|
// Generate random bytes for each character
|
|
531
|
-
const randomBytes = CryptoJS.lib.WordArray.random(1);
|
|
532
|
-
const randomValue = randomBytes.words[0];
|
|
533
|
-
const charIndex = Math.abs(randomValue) % chars.length;
|
|
566
|
+
const randomBytes: CryptoJS.lib.WordArray = CryptoJS.lib.WordArray.random(1);
|
|
567
|
+
const randomValue: number = randomBytes.words[0];
|
|
568
|
+
const charIndex: number = Math.abs(randomValue) % chars.length;
|
|
534
569
|
complexKey += chars[charIndex];
|
|
535
570
|
}
|
|
536
571
|
|
|
@@ -572,15 +607,15 @@ export class DyFM_Crypto {
|
|
|
572
607
|
}
|
|
573
608
|
|
|
574
609
|
// Convert from URL-safe base64
|
|
575
|
-
const base64 = encryptedData
|
|
610
|
+
const base64: string = encryptedData
|
|
576
611
|
.replace(/-/g, '+')
|
|
577
612
|
.replace(/_/g, '/');
|
|
578
613
|
|
|
579
614
|
// Parse the combined data
|
|
580
|
-
const combined = CryptoJS.enc.Base64.parse(base64);
|
|
615
|
+
const combined: CryptoJS.lib.WordArray = CryptoJS.enc.Base64.parse(base64);
|
|
581
616
|
|
|
582
617
|
// For now, just check if the data has minimum required length
|
|
583
|
-
const minLength = (16 + 16 + 16) / 4; // IV + Salt + minimum ciphertext
|
|
618
|
+
const minLength: number = (16 + 16 + 16) / 4; // IV + Salt + minimum ciphertext
|
|
584
619
|
|
|
585
620
|
if (combined.words.length < minLength) {
|
|
586
621
|
return {
|
|
@@ -612,7 +647,7 @@ export class DyFM_Crypto {
|
|
|
612
647
|
* Gets default error settings with enhanced debugging information
|
|
613
648
|
*/
|
|
614
649
|
private static getDefaultErrorSettings(operation: string, error?: any): DyFM_Error_Settings {
|
|
615
|
-
const baseSettings = {
|
|
650
|
+
const baseSettings: DyFM_Error_Settings = {
|
|
616
651
|
status: (error as DyFM_Error)?.___status ?? (error as any)?.status ?? 401,
|
|
617
652
|
message: `Crypto operation "${operation}" failed.`,
|
|
618
653
|
error: error,
|
|
@@ -625,7 +660,17 @@ export class DyFM_Crypto {
|
|
|
625
660
|
'\n 1) Wrong encryption key, ' +
|
|
626
661
|
'\n 2) Corrupted encrypted data, ' +
|
|
627
662
|
'\n 3) Version incompatibility, ' +
|
|
628
|
-
'\n 4) Data was encrypted with different parameters
|
|
663
|
+
'\n 4) Data was encrypted with different parameters, ' +
|
|
664
|
+
'\n 5) Data truncation during transmission (check HTTP header size limits, URL length limits), ' +
|
|
665
|
+
'\n 6) Missing base64 padding (should be automatically handled, but may indicate transmission issues).';
|
|
666
|
+
|
|
667
|
+
// Add specific guidance for truncation issues (like the "18 bytes" error)
|
|
668
|
+
baseSettings.message += '\n\nFor truncation issues (e.g., "received 18 bytes"): ' +
|
|
669
|
+
'\n - Check if data is being truncated in HTTP headers (Nginx default: 4-8KB, configurable), ' +
|
|
670
|
+
'\n - Verify URL parameter length limits if passed via query string, ' +
|
|
671
|
+
'\n - Check database field size limits if stored, ' +
|
|
672
|
+
'\n - Ensure proxy/load balancer header size limits are sufficient, ' +
|
|
673
|
+
'\n - Verify the encrypted data string length matches expected size before decryption.';
|
|
629
674
|
} else if (operation === 'encrypt') {
|
|
630
675
|
baseSettings.message += '\nThis usually indicates: ' +
|
|
631
676
|
'\n 1) Invalid input data, ' +
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.util.spec.d.ts","sourceRoot":"","sources":["../../../../src/_modules/crypto/_collections/crypto.util.spec.ts"],"names":[],"mappings":""}
|