npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jagad.cloud/crypto

v1.1.0

Published

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

Readme

@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

npm install @jagad.cloud/crypto
# atau
yarn add @jagad.cloud/crypto
# atau
pnpm add @jagad.cloud/crypto

🔑 Daftar Fungsi & Penggunaan

1. ensureDeviceKey()

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)

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()

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)

import { encryptPrivateKey } from '@jagad.cloud/crypto';

const encryptedPrivateKey = await encryptPrivateKey(privateKeyRaw, derivedKey);
  • Mengenkripsi private key dengan AES-GCM derived key.

5. decryptPrivateKey(encryptedPackage, derivedKey)

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

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

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

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