@angular-helpers/security 21.0.3 → 21.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.es.md CHANGED
@@ -15,6 +15,13 @@ Paquete de seguridad para aplicaciones Angular que previene ataques comunes como
15
15
  - **Análisis de Complejidad**: Detecta patrones peligrosos antes de la ejecución.
16
16
  - **Modo Seguro**: Solo permite patrones verificados como seguros.
17
17
 
18
+ ### **Web Crypto API**
19
+
20
+ - **Cifrado/Descifrado**: Soporte AES-GCM para manejo seguro de datos
21
+ - **Hashing**: SHA-256 y otros algoritmos
22
+ - **Gestión de Claves**: Generar, importar y exportar claves criptográficas
23
+ - **Aleatorio Seguro**: Valores aleatorios criptográficamente seguros
24
+
18
25
  ### **Patrón Builder**
19
26
 
20
27
  - **API Fluida**: Construye expresiones regulares de forma intuitiva.
@@ -93,6 +100,51 @@ const result = await RegexSecurityService.builder()
93
100
  .execute('12345', this.securityService);
94
101
  ```
95
102
 
103
+ ### **WebCryptoService**
104
+
105
+ ```typescript
106
+ import { WebCryptoService } from '@angular-helpers/security';
107
+
108
+ export class SecureStorageComponent {
109
+ private cryptoService = inject(WebCryptoService);
110
+
111
+ async hashPassword(password: string): Promise<string> {
112
+ return await this.cryptoService.hash(password, 'SHA-256');
113
+ }
114
+
115
+ async encryptData(
116
+ data: string,
117
+ ): Promise<{ ciphertext: ArrayBuffer; iv: Uint8Array; key: CryptoKey }> {
118
+ const key = await this.cryptoService.generateAesKey(256);
119
+ const { ciphertext, iv } = await this.cryptoService.encryptAes(key, data);
120
+ return { ciphertext, iv, key };
121
+ }
122
+
123
+ async decryptData(ciphertext: ArrayBuffer, iv: Uint8Array, key: CryptoKey): Promise<string> {
124
+ return await this.cryptoService.decryptAes(key, ciphertext, iv);
125
+ }
126
+
127
+ async exportKeyForStorage(key: CryptoKey): Promise<JsonWebKey> {
128
+ return await this.cryptoService.exportKey(key);
129
+ }
130
+
131
+ async importKeyFromStorage(jwk: JsonWebKey): Promise<CryptoKey> {
132
+ return await this.cryptoService.importAesKey(jwk);
133
+ }
134
+
135
+ generateSecureToken(length: number = 32): string {
136
+ const bytes = this.cryptoService.generateRandomBytes(length);
137
+ return Array.from(bytes)
138
+ .map((b) => b.toString(16).padStart(2, '0'))
139
+ .join('');
140
+ }
141
+
142
+ generateUUID(): string {
143
+ return this.cryptoService.randomUUID();
144
+ }
145
+ }
146
+ ```
147
+
96
148
  ## 📊 Niveles de Riesgo
97
149
 
98
150
  | Nivel | Descripción | Acción |
package/README.md CHANGED
@@ -15,6 +15,13 @@ Security package for Angular applications that prevents common attacks like ReDo
15
15
  - **Complexity Analysis**: Detects dangerous patterns before execution.
16
16
  - **Safe Mode**: Only allows patterns verified as safe.
17
17
 
18
+ ### **Web Crypto API**
19
+
20
+ - **Encryption/Decryption**: AES-GCM support for secure data handling
21
+ - **Hashing**: SHA-256 and other algorithms
22
+ - **Key Management**: Generate, import, and export cryptographic keys
23
+ - **Secure Random**: Cryptographically secure random values
24
+
18
25
  ### **Builder Pattern**
19
26
 
20
27
  - **Fluent API**: Intuitively build regular expressions.
@@ -163,6 +170,51 @@ export class FormValidationComponent {
163
170
  }
164
171
  ```
165
172
 
173
+ ### **WebCryptoService**
174
+
175
+ ```typescript
176
+ import { WebCryptoService } from '@angular-helpers/security';
177
+
178
+ export class SecureStorageComponent {
179
+ private cryptoService = inject(WebCryptoService);
180
+
181
+ async hashPassword(password: string): Promise<string> {
182
+ return await this.cryptoService.hash(password, 'SHA-256');
183
+ }
184
+
185
+ async encryptData(
186
+ data: string,
187
+ ): Promise<{ ciphertext: ArrayBuffer; iv: Uint8Array; key: CryptoKey }> {
188
+ const key = await this.cryptoService.generateAesKey(256);
189
+ const { ciphertext, iv } = await this.cryptoService.encryptAes(key, data);
190
+ return { ciphertext, iv, key };
191
+ }
192
+
193
+ async decryptData(ciphertext: ArrayBuffer, iv: Uint8Array, key: CryptoKey): Promise<string> {
194
+ return await this.cryptoService.decryptAes(key, ciphertext, iv);
195
+ }
196
+
197
+ async exportKeyForStorage(key: CryptoKey): Promise<JsonWebKey> {
198
+ return await this.cryptoService.exportKey(key);
199
+ }
200
+
201
+ async importKeyFromStorage(jwk: JsonWebKey): Promise<CryptoKey> {
202
+ return await this.cryptoService.importAesKey(jwk);
203
+ }
204
+
205
+ generateSecureToken(length: number = 32): string {
206
+ const bytes = this.cryptoService.generateRandomBytes(length);
207
+ return Array.from(bytes)
208
+ .map((b) => b.toString(16).padStart(2, '0'))
209
+ .join('');
210
+ }
211
+
212
+ generateUUID(): string {
213
+ return this.cryptoService.randomUUID();
214
+ }
215
+ }
216
+ ```
217
+
166
218
  ## 🔧 Advanced Configuration
167
219
 
168
220
  ### **Security Options**
@@ -1,5 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, DestroyRef, Injectable, makeEnvironmentProviders } from '@angular/core';
2
+ import { inject, DestroyRef, Injectable, PLATFORM_ID, makeEnvironmentProviders } from '@angular/core';
3
+ import { isPlatformBrowser } from '@angular/common';
3
4
 
4
5
  /**
5
6
  * Security service for regular expressions that prevents ReDoS
@@ -411,8 +412,79 @@ class RegexSecurityBuilder {
411
412
  }
412
413
  }
413
414
 
415
+ class WebCryptoService {
416
+ platformId = inject(PLATFORM_ID);
417
+ isSupported() {
418
+ return isPlatformBrowser(this.platformId) && 'crypto' in window && 'subtle' in crypto;
419
+ }
420
+ get subtle() {
421
+ if (!this.isSupported()) {
422
+ throw new Error('Web Crypto API not supported in this environment');
423
+ }
424
+ return crypto.subtle;
425
+ }
426
+ ensureSecureContext() {
427
+ if (!window.isSecureContext) {
428
+ throw new Error('Web Crypto API requires a secure context (HTTPS)');
429
+ }
430
+ }
431
+ async hash(data, algorithm = 'SHA-256') {
432
+ this.ensureSecureContext();
433
+ const buffer = typeof data === 'string' ? new TextEncoder().encode(data) : data;
434
+ const hashBuffer = await this.subtle.digest(algorithm, buffer);
435
+ return this.bufferToHex(hashBuffer);
436
+ }
437
+ async generateAesKey(length = 256) {
438
+ this.ensureSecureContext();
439
+ return this.subtle.generateKey({ name: 'AES-GCM', length }, true, ['encrypt', 'decrypt']);
440
+ }
441
+ async encryptAes(key, data) {
442
+ this.ensureSecureContext();
443
+ const buffer = typeof data === 'string' ? new TextEncoder().encode(data) : data;
444
+ const iv = crypto.getRandomValues(new Uint8Array(12));
445
+ const ciphertext = await this.subtle.encrypt({ name: 'AES-GCM', iv }, key, buffer);
446
+ return { ciphertext, iv };
447
+ }
448
+ async decryptAes(key, ciphertext, iv) {
449
+ this.ensureSecureContext();
450
+ const decrypted = await this.subtle.decrypt({ name: 'AES-GCM', iv }, key, ciphertext);
451
+ return new TextDecoder().decode(decrypted);
452
+ }
453
+ async exportKey(key) {
454
+ this.ensureSecureContext();
455
+ return this.subtle.exportKey('jwk', key);
456
+ }
457
+ async importAesKey(jwk) {
458
+ this.ensureSecureContext();
459
+ return this.subtle.importKey('jwk', jwk, { name: 'AES-GCM' }, true, ['encrypt', 'decrypt']);
460
+ }
461
+ generateRandomBytes(length) {
462
+ if (!this.isSupported()) {
463
+ throw new Error('Web Crypto API not supported');
464
+ }
465
+ return crypto.getRandomValues(new Uint8Array(length));
466
+ }
467
+ randomUUID() {
468
+ if (!this.isSupported()) {
469
+ throw new Error('Web Crypto API not supported');
470
+ }
471
+ return crypto.randomUUID();
472
+ }
473
+ bufferToHex(buffer) {
474
+ return Array.from(new Uint8Array(buffer))
475
+ .map((b) => b.toString(16).padStart(2, '0'))
476
+ .join('');
477
+ }
478
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebCryptoService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
479
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebCryptoService });
480
+ }
481
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: WebCryptoService, decorators: [{
482
+ type: Injectable
483
+ }] });
484
+
414
485
  const defaultSecurityConfig = {
415
486
  enableRegexSecurity: true,
487
+ enableWebCrypto: true,
416
488
  defaultTimeout: 5000,
417
489
  safeMode: false,
418
490
  };
@@ -422,14 +494,20 @@ function provideSecurity(config = {}) {
422
494
  if (mergedConfig.enableRegexSecurity) {
423
495
  providers.push(RegexSecurityService);
424
496
  }
497
+ if (mergedConfig.enableWebCrypto) {
498
+ providers.push(WebCryptoService);
499
+ }
425
500
  return makeEnvironmentProviders(providers);
426
501
  }
427
502
  function provideRegexSecurity() {
428
503
  return makeEnvironmentProviders([RegexSecurityService]);
429
504
  }
505
+ function provideWebCrypto() {
506
+ return makeEnvironmentProviders([WebCryptoService]);
507
+ }
430
508
 
431
509
  /**
432
510
  * Generated bundle index. Do not edit.
433
511
  */
434
512
 
435
- export { RegexSecurityBuilder, RegexSecurityService, defaultSecurityConfig, provideRegexSecurity, provideSecurity };
513
+ export { RegexSecurityBuilder, RegexSecurityService, WebCryptoService, defaultSecurityConfig, provideRegexSecurity, provideSecurity, provideWebCrypto };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular-helpers/security",
3
- "version": "21.0.3",
3
+ "version": "21.0.4",
4
4
  "description": "Angular security helpers for preventing ReDoS and other security vulnerabilities",
5
5
  "keywords": [
6
6
  "angular",
@@ -151,14 +151,40 @@ declare class RegexSecurityBuilder {
151
151
  execute(text: string, service: RegexSecurityService): Promise<RegexTestResult>;
152
152
  }
153
153
 
154
+ type HashAlgorithm = 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512';
155
+ type AesKeyLength = 128 | 192 | 256;
156
+ interface AesEncryptResult {
157
+ ciphertext: ArrayBuffer;
158
+ iv: Uint8Array;
159
+ }
160
+ declare class WebCryptoService {
161
+ private readonly platformId;
162
+ isSupported(): boolean;
163
+ private get subtle();
164
+ private ensureSecureContext;
165
+ hash(data: string | ArrayBuffer, algorithm?: HashAlgorithm): Promise<string>;
166
+ generateAesKey(length?: AesKeyLength): Promise<CryptoKey>;
167
+ encryptAes(key: CryptoKey, data: string | ArrayBuffer): Promise<AesEncryptResult>;
168
+ decryptAes(key: CryptoKey, ciphertext: ArrayBuffer, iv: Uint8Array<ArrayBuffer>): Promise<string>;
169
+ exportKey(key: CryptoKey): Promise<JsonWebKey>;
170
+ importAesKey(jwk: JsonWebKey): Promise<CryptoKey>;
171
+ generateRandomBytes(length: number): Uint8Array;
172
+ randomUUID(): string;
173
+ private bufferToHex;
174
+ static ɵfac: i0.ɵɵFactoryDeclaration<WebCryptoService, never>;
175
+ static ɵprov: i0.ɵɵInjectableDeclaration<WebCryptoService>;
176
+ }
177
+
154
178
  interface SecurityConfig {
155
179
  enableRegexSecurity?: boolean;
180
+ enableWebCrypto?: boolean;
156
181
  defaultTimeout?: number;
157
182
  safeMode?: boolean;
158
183
  }
159
184
  declare const defaultSecurityConfig: SecurityConfig;
160
185
  declare function provideSecurity(config?: SecurityConfig): EnvironmentProviders;
161
186
  declare function provideRegexSecurity(): EnvironmentProviders;
187
+ declare function provideWebCrypto(): EnvironmentProviders;
162
188
 
163
- export { RegexSecurityBuilder, RegexSecurityService, defaultSecurityConfig, provideRegexSecurity, provideSecurity };
164
- export type { RegexBuilderOptions, RegexSecurityConfig, RegexSecurityResult, RegexTestResult, SecurityConfig };
189
+ export { RegexSecurityBuilder, RegexSecurityService, WebCryptoService, defaultSecurityConfig, provideRegexSecurity, provideSecurity, provideWebCrypto };
190
+ export type { AesEncryptResult, AesKeyLength, HashAlgorithm, RegexBuilderOptions, RegexSecurityConfig, RegexSecurityResult, RegexTestResult, SecurityConfig };