UNPKG

@jagad.cloud/crypto

Version:

Browser-safe helpers for password-derived keys, keypair generation, and private-key encryption using Web Crypto API.

213 lines (146 loc) 5.66 kB
# @jagad.cloud/crypto (Secure Crypto Library) `@jagad.cloud/crypto` adalah library JavaScript/TypeScript yang memanfaatkan **Web Crypto API** untuk enkripsi pesan, manajemen kunci, dan komunikasi multi-user yang aman. Cocok untuk aplikasi web yang membutuhkan standar keamanan tinggi. --- ## 🔑 Fitur Utama * Device-specific key untuk menambah keamanan * Password-derived AES keys * RSA key pair untuk wrap/unwrap AES keys * Enkripsi/dekripsi private key * Multi-user secure messaging * Re-encrypt private key saat password diganti * Standar internasional & praktik terbaik keamanan --- ## 🔐 Keamanan & Praktik Terbaik * **Device Key:** * Tidak bisa diexport menambah entropy unik per device * **AES-GCM:** * IV random + tag 128-bit menjamin integritas pesan * **RSA-OAEP:** * Wrap/unwrap AES key aman untuk multi-user * **PBKDF2:** * 200.000 iterasi proteksi password yang kuat * **Multi-user Support:** * Tanpa mengekspos private key ke server atau user lain > Semua praktik di atas mengikuti standar industri internasional, termasuk rekomendasi NIST dan W3C untuk Web Crypto API. --- ## 📦 Instalasi ```bash npm install @jagad.cloud/crypto # atau yarn add @jagad.cloud/crypto # atau pnpm add @jagad.cloud/crypto ``` --- ## 🔑 Daftar Fungsi & Penggunaan ### 1. `ensureDeviceKey()` ```ts import { ensureDeviceKey } from '@jagad.cloud/crypto'; const deviceKey = await ensureDeviceKey(); console.log(deviceKey.byteLength); // 32 ``` * Membuat device-specific secret key (32 bytes) & menyimpannya di IndexedDB. * Jika device key sudah ada, dikembalikan dari storage. --- ### 2. `deriveKeyFromPassword(password, salt)` ```ts import { deriveKeyFromPassword } from '@jagad.cloud/crypto'; const derivedKey = await deriveKeyFromPassword("password123", "salt-test"); console.log(derivedKey.type); // secret ``` * Menghasilkan AES-GCM key dari password + salt + deviceKey. * PBKDF2 dengan 200.000 iterasi, hash SHA-256. --- ### 3. `generateKeyPair()` ```ts import { generateKeyPair } from '@jagad.cloud/crypto'; const { publicKey, privateKeyRaw } = await generateKeyPair(); ``` * Membuat RSA key pair untuk user (wrap/unwrap AES key). --- ### 4. `encryptPrivateKey(privateKeyRaw, derivedKey)` ```ts import { encryptPrivateKey } from '@jagad.cloud/crypto'; const encryptedPrivateKey = await encryptPrivateKey(privateKeyRaw, derivedKey); ``` * Mengenkripsi private key dengan AES-GCM derived key. --- ### 5. `decryptPrivateKey(encryptedPackage, derivedKey)` ```ts import { decryptPrivateKey } from '@jagad.cloud/crypto'; const privKey = await decryptPrivateKey(encryptedPrivateKey, derivedKey); console.log(privKey.type); // private ``` * Mendekripsi private key yang terenkripsi. --- ### 6. AES Utilities ```ts import { generateAesKey, encryptText, decryptText, wrapAesKey, unwrapAesKey } from '@jagad.cloud/crypto'; const aesKey = await generateAesKey(); const { ciphertext, iv } = await encryptText("Halo dunia!", aesKey); const decrypted = await decryptText(ciphertext, iv, aesKey); // Wrap/unwrap AES key dengan RSA const wrapped = await wrapAesKey(aesKey, publicKey); const unwrapped = await unwrapAesKey(wrapped, privateKey); ``` --- ### 7. Multi-user Secure Messaging * Setiap user memiliki public key & encrypted private key * Pesan dienkripsi dengan AES key * AES key dienkripsi (wrap) untuk public key masing-masing user * Hanya user dengan private key bisa decrypt --- ### 8. Re-encrypt Private Key saat Password Diganti ```ts import { decryptPrivateKey, encryptPrivateKey } from '@jagad.cloud/crypto'; // Decrypt dengan derived key lama const privKeyOld = await decryptPrivateKey(encryptedPrivateKeyOld, derivedKeyOld); // Export raw private key const privRaw = await crypto.subtle.exportKey("pkcs8", privKeyOld); // Encrypt ulang dengan derived key baru const encryptedPrivateKeyNew = await encryptPrivateKey(privRaw, derivedKeyNew); ``` --- ## 📈 Diagram Alur ```mermaid graph TD PT["Plaintext Message"] AESK["AES-GCM Key"] ENC["Encrypted Message (AES-GCM)"] USER1_PUB["User1 Public Key (RSA-OAEP)"] USER2_PUB["User2 Public Key (RSA-OAEP)"] WRAP1["Wrapped AES Key for User1"] WRAP2["Wrapped AES Key for User2"] USER1_PRIV["User1 Private Key + Derived Key"] USER2_PRIV["User2 Private Key + Derived Key"] DECRYPT1["User1 Decrypts AES Key & Message"] DECRYPT2["User2 Decrypts AES Key & Message"] NEW_DK["New Derived Key (after password change)"] RE_ENC["Re-encrypt Private Key with New Derived Key"] PT --> AESK AESK --> ENC AESK --> WRAP1 AESK --> WRAP2 USER1_PUB --> WRAP1 USER2_PUB --> WRAP2 WRAP1 --> USER1_PRIV --> DECRYPT1 --> ENC WRAP2 --> USER2_PRIV --> DECRYPT2 --> ENC USER1_PRIV --> RE_ENC --> NEW_DK USER2_PRIV --> RE_ENC ``` --- ## 📊 Hasil Test & Coverage ``` --------------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s --------------|---------|----------|---------|---------|------------------- All files | 100 | 100 | 100 | 100 | aes.ts | 100 | 100 | 100 | 100 | index.ts | 100 | 100 | 100 | 100 | indexeddb.ts | 100 | 100 | 100 | 100 | utils.ts | 100 | 100 | 100 | 100 | --------------|---------|----------|---------|---------|------------------- ``` * Semua test lulus (12 test) * Framework: Jest + fake-indexeddb * Mencakup semua fungsi dan branch coverage