UNPKG

@anderson.tec12/utils

Version:

[![npm version](https://badge.fury.io/js/%40anderson.tec12%2Futils.svg)](https://badge.fury.io/js/%40anderson.tec12%2Futils) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

90 lines (76 loc) 2.21 kB
class SecureStorage { private secret: string; private encoder = new TextEncoder(); private decoder = new TextDecoder(); constructor(secret: string) { this.secret = secret; } private async getKey(): Promise<CryptoKey> { const keyMaterial = await window.crypto.subtle.importKey( 'raw', this.encoder.encode(this.secret), 'PBKDF2', false, ['deriveKey'] ); return await window.crypto.subtle.deriveKey( { name: 'PBKDF2', salt: this.encoder.encode('saltaqui123'), iterations: 100000, hash: 'SHA-256', }, keyMaterial, { name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt'] ); } async setItem(key: string, value: any): Promise<void> { const iv = window.crypto.getRandomValues(new Uint8Array(12)); const encoded = this.encoder.encode(JSON.stringify(value)); const cryptoKey = await this.getKey(); const encrypted = await window.crypto.subtle.encrypt( { name: 'AES-GCM', iv: iv, }, cryptoKey, encoded ); const data = { iv: Array.from(iv), value: Array.from(new Uint8Array(encrypted)), }; localStorage.setItem(key, JSON.stringify(data)); } async getItem<T>(key: string): Promise<T | null> { const item = localStorage.getItem(key); if (!item) return null; const data = JSON.parse(item); const iv = new Uint8Array(data.iv); const encryptedData = new Uint8Array(data.value); const cryptoKey = await this.getKey(); try { const decrypted = await window.crypto.subtle.decrypt( { name: 'AES-GCM', iv: iv, }, cryptoKey, encryptedData ); return JSON.parse(this.decoder.decode(decrypted)) as T; } catch (e) { console.error('Erro ao descriptografar:', e); return null; } } removeItem(key: string): void { localStorage.removeItem(key); } clear(): void { localStorage.clear(); } } export const secureStorage = new SecureStorage('08dc3b0a3a70de0e0b82a6168814f697');