@athsra/crypto
v2.2.0
Published
athsra core crypto — Argon2id KDF + AES-256-GCM (WebCrypto). Worker + CLI 공유. MIT.
Maintainers
Readme
@athsra/crypto
athsra core crypto primitives — Argon2id KDF + AES-256-GCM authenticated encryption. Worker + CLI 양쪽에서 동일 결과 보장 (WebCrypto + @noble/hashes).
E2EE secret manager athsra 의 cryptographic 기반.
설치
bun add @athsra/crypto사용
import {
deriveKey,
encrypt,
decrypt,
randomSalt,
randomNonce,
toBase64,
fromBase64,
DEFAULT_KDF,
type SecretEnvelope,
} from '@athsra/crypto';
// 1. Argon2id KDF (m=64MB, t=3, p=1, OWASP 2024+ 권고)
const password = 'master-password';
const salt = randomSalt(); // 16 bytes random
const key = deriveKey(password, salt); // 32 bytes (AES-256 key)
// 2. AES-256-GCM encrypt
const blob = await encrypt(key, 'plaintext');
// blob = { ciphertext: Uint8Array, nonce: Uint8Array }
// 3. SecretEnvelope wire format (Worker R2 + CLI 호환)
const envelope: SecretEnvelope = {
version: 1,
alg: 'aes-256-gcm',
kdf: 'argon2id',
kdf_params: DEFAULT_KDF,
salt: toBase64(salt),
nonce: toBase64(blob.nonce),
ciphertext: toBase64(blob.ciphertext),
version_id: `v${Date.now()}`,
updated_at: new Date().toISOString(),
};
// 4. Decrypt (다른 머신 / 시점)
const sameKey = deriveKey(password, fromBase64(envelope.salt));
const plain = await decrypt(sameKey, {
ciphertext: fromBase64(envelope.ciphertext),
nonce: fromBase64(envelope.nonce),
});
// plain === 'plaintext'API
| Export | 설명 |
|---|---|
| deriveKey(password, salt) | Argon2id (m=64MB, t=3, p=1) → 32 bytes |
| encrypt(key, plaintext) | AES-256-GCM → { ciphertext, nonce } (auth tag 포함) |
| decrypt(key, blob) | auth tag 검증 후 plaintext. 실패 시 throw |
| randomSalt() / randomNonce() | crypto.getRandomValues 16 / 12 bytes |
| toBase64(uint8) / fromBase64(str) | wire encoding |
| DEFAULT_KDF | { m: 65536, t: 3, p: 1 } |
| SecretEnvelope (type) | wire format spec |
의존성
@noble/hashes— Argon2id (paulmillr audited, 0 deps, Cure53 부분 audit)- WebCrypto SubtleCrypto — AES-256-GCM (native, NIST SP 800-38D / FIPS 140-2 approved)
호환성
암호 프리미티브(WebCrypto SubtleCrypto)는 Worker (Cloudflare Workers / V8 isolate) · Bun · Node.js 어디서도 동일 결과 — 같은 (password, salt) → 같은 key (deterministic).
런타임 요구: 이 패키지는 raw TypeScript 를 export 하므로(package.json engines.bun >=1.3),
소비 런타임이 TS 를 직접 실행/스트립할 수 있어야 한다. Bun 이 공식 대상이다. Node 는 22.6+
에서 --experimental-strip-types(또는 22.18+ 기본 type-stripping)로만 import 가능하고, Node 18/20 은
ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING 로 실패한다. Node 18+ 를 "지원"한다고 적었던 이전
문구는 오류였다(audit P3-01). 트랜스파일된 소비가 필요하면 번들러(esbuild/tsup 등)로 감싸 쓴다.
License
MIT — see LICENSE-MIT.
