A small, public playground for @asafarim/appsafe. Encrypt with a shared password or for a public key, then decrypt with the matching secret — the same calls you would ship in your own app.
Web Crypto APIAES-256-GCMPBKDF2 or ECDH P-256TypeScript
appsafe-demo
// password mode
await encryptBytes(file, password);
// public-key mode
await encryptBytesForRecipients(file, publicKey);
// stays in this browser tab
01 / LIVE PLAYGROUND
Use the public package directly.
This demo has no owner gate because its purpose is to document the reusable npm API. Every transform and every generated key stays in browser memory.
Not sent over the network
Encrypted payloadwaiting
Encrypt text to inspect the payload bytes.
Payloads are self-describing: inspectAppSafePayload() reports the mode, so decrypting with the wrong method fails with MODE_MISMATCH instead of guessing.
02 / TWO METHODS
Same core, different custody.
Both methods finish with AES-256-GCM over an authenticated, versioned header. They differ in where the key comes from and who must keep a secret.
PASSWORD MODE / ENVELOPE v1
One shared secret encrypts and decrypts.
PasswordTyped or injected at runtime.
Random salt + PBKDF2-HMAC-SHA-256600,000 iterations by default.
AES-256-GCM keyDerived per payload; never stored.
Encrypt with a random 96-bit IVThe header is authenticated as additional data.
Authentication covers the header, every recipient entry, and the ciphertext. Run the checks to see the exact error codes your app should handle.
Each check creates fresh, throwaway keys and payloads in this tab, then tries to break them. Every failure must be a typed AppSafeCryptoError — never partial plaintext.
Wrong passwordpassword modeINVALID_PASSWORD_OR_DATAnot run
Tampered password payloadpassword modeINVALID_PASSWORD_OR_DATAnot run
Wrong private keypublic-key modeNO_MATCHING_KEYnot run
Tampered public-key payloadpublic-key modeINVALID_KEY_OR_DATAnot run
Truncated payloadeither modeINVALID_PAYLOADnot run
Password used on a public-key payloadeither modeMODE_MISMATCHnot run
Malformed public keypublic-key modeINVALID_KEYnot run
04 / COPYABLE RECIPES
A few calls are enough.
Install the package, supply a password or keys you manage, and keep the returned bytes wherever your app needs them.
import { generateKeyPair } from "@asafarim/appsafe";
const { publicKey, privateKey, fingerprint } = await generateKeyPair();
// publicKey -> safe to commit or share (for example .appsafe/key.pub)
// privateKey -> secret: store it privately, never commit or log it
Public key / file round-trip
import {
decryptBytesWithPrivateKey,
encryptBytesForRecipients,
} from "@asafarim/appsafe";
const input = new Uint8Array(await file.arrayBuffer());
// Anyone with the public key can encrypt...
const encrypted = await encryptBytesForRecipients(input, publicKey);
// ...only the private-key holder can decrypt.
const plaintext = await decryptBytesWithPrivateKey(encrypted, privateKey);
Public key / multiple recipients
import { encryptTextForRecipients } from "@asafarim/appsafe";
const encrypted = await encryptTextForRecipients(note, [
ownerPublicKey,
deployPublicKey,
]);
// Each recipient decrypts with its own private key.
Detect the mode, then decrypt
import {
AppSafeCryptoError,
decryptBytes,
decryptBytesWithPrivateKey,
inspectAppSafePayload,
} from "@asafarim/appsafe";
try {
const info = inspectAppSafePayload(payload);
const plaintext = info.mode === "password"
? await decryptBytes(payload, password)
: await decryptBytesWithPrivateKey(payload, privateKey);
} catch (error) {
if (error instanceof AppSafeCryptoError) {
console.warn(error.code); // e.g. NO_MATCHING_KEY, never the key itself
}
}
CLI / encrypt a private app folder
# Public-key mode for a private app folder (CLI)
appsafe init --mode public-key # config: .appsafe/key.pub + .appsafe/key.txt
appsafe keygen # private key is added to .gitignore
appsafe encrypt # needs only the public key
appsafe decrypt # needs the private key
appsafe rekey # migrate password artifacts to the configured mode
A / BROWSER CORE
Both methods
pnpm add @asafarim/appsafe
Password and public-key encryption, key generation, and payload inspection run anywhere Web Crypto supports AES-GCM, PBKDF2, HKDF, and ECDH P-256: evergreen browsers, Node 20+, and Deno.
B / CLI ONLY
Files and folders
pnpm add -D @asafarim/appsafe-cli
Key files, folder archives, per-target modes, .gitignore management, and rekey migration need a filesystem, so they live in the Node.js CLI.
C / FORMAT
Not Age-compatible
ECDH-P256+HKDF-SHA256+A256GCM
Uses the same recipient/identity model as Age, built only from Web Crypto primitives. Age files and keys cannot be read or written.