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

@agentdock/crypto

v0.0.11

Published

E2E encryption for AgentDock — AES-256-GCM, key derivation, Web Crypto API

Downloads

1,385

Readme

@agentdock/crypto

E2E 加密模块 — AES-256-GCM + Ed25519 + NaCl Box/SecretBox,浏览器与 Node.js 22+ 通用。

概述

crypto 包实现 AgentDock 的端到端加密。所有敏感数据在离开用户设备前加密,服务端永远看不到明文

支持两种运行环境:

  • 浏览器:Web Crypto API(AES-GCM、HKDF、HMAC)
  • Node.js 22+:同样走 Web Crypto API(globalThis.crypto.subtle
  • tweetnacl:NaCl Box / SecretBox(跨平台兼容)

在架构中的位置

wire → crypto → sdk → web
wire → crypto → daemon

依赖 wire 的类型定义,被 sdk/daemon/web 使用。

模块结构

src/
├── aes.ts       # AES-256-GCM 加密/解密(Web Crypto API)
├── auth.ts      # Ed25519 认证挑战(签名/验签)
├── box.ts       # NaCl Box 非对称加密(密钥交付)
├── secretbox.ts # NaCl SecretBox 对称加密(legacy 兼容)
├── content.ts   # Content keypair 派生(从密钥树推导 Box 密钥对)
├── keys.ts      # 密钥派生树(HKDF-SHA512 分层派生)
├── hmac.ts      # HMAC-SHA512(消息认证码)
├── encoding.ts  # Base64 / Base64URL 编解码
├── random.ts    # 安全随机数生成
└── index.ts     # Barrel exports

API 参考

AES-256-GCM (aes.ts)

import { encryptAesGcm, decryptAesGcm } from '@agentdock/crypto';

// 加密:返回 { c: base64(iv + ciphertext + tag), n: base64(nonce) }
const bundle = await encryptAesGcm(data: Uint8Array, key: Uint8Array);

// 解密:返回原始明文 Uint8Array
const plaintext = await decryptAesGcm(bundle, key);

Bundle 格式:iv(12 bytes) + ciphertext + tag(16 bytes),整体 Base64 编码。

Ed25519 认证 (auth.ts)

import { authChallenge, verifyChallenge } from '@agentdock/crypto';

// 从 seed 生成 Ed25519 密钥对 + 签名挑战
const result = await authChallenge(seed: Uint8Array);
// { publicKey, secretKey, challenge, signature }

// 验证签名
const valid = await verifyChallenge(challenge, signature, publicKey);

注意:直接使用 seed 作为 Ed25519 种子,不做额外 deriveKey(与 Happy 对齐,见 L23)。

NaCl Box (box.ts)

import { encryptBox, decryptBox, boxPublicKeyFromSecretKey } from '@agentdock/crypto';

// 非对称加密(发送方用接收方公钥加密)
const bundle = encryptBox(data: Uint8Array, recipientPublicKey: Uint8Array);

// 解密(接收方用自己的私钥 + 发送方公钥解密)
const plaintext = decryptBox(bundle, secretKey: Uint8Array);

// 从 X25519 私钥推导公钥
const publicKey = boxPublicKeyFromSecretKey(secretKey);

NaCl SecretBox (secretbox.ts)

import { encryptSecretBox, decryptSecretBox } from '@agentdock/crypto';

// 对称加密(legacy 兼容)
const bundle = encryptSecretBox(data: Uint8Array, secret: Uint8Array);
const plaintext = decryptSecretBox(bundle, secret);

密钥派生树 (keys.ts)

import { deriveSecretKeyTreeRoot, deriveSecretKeyTreeChild, deriveKey } from '@agentdock/crypto';

// 从根密钥 + 标签派生子密钥
const root = await deriveSecretKeyTreeRoot(masterSecret, 'Happy EnCoder');
const child = await deriveSecretKeyTreeChild(root, 'content');

// 底层:HKDF-SHA512 派生
const key = await deriveKey(secret, label, segments);

Content Keypair (content.ts)

import { deriveContentKeyPair } from '@agentdock/crypto';

// 'Happy EnCoder' + ['content'] + SHA-512[0:32] → NaCl Box keypair
const { publicKey, secretKey } = await deriveContentKeyPair(secret);

HMAC-SHA512 (hmac.ts)

import { hmacSha512 } from '@agentdock/crypto';
const mac = await hmacSha512(key, data);

编码 (encoding.ts)

import { encodeBase64, decodeBase64, encodeBase64Url, decodeBase64Url } from '@agentdock/crypto';

开发

# 运行测试(111 tests)
pnpm --filter @agentdock/crypto test

# 覆盖率(目标 95%+)
pnpm --filter @agentdock/crypto test:coverage

设计决策

  • Web Crypto API 优先:AES-GCM、HKDF、HMAC 全走 crypto.subtle,不引入额外依赖
  • tweetnacl 用于 NaCl:Box/SecretBox 使用 tweetnacl,因为 Web Crypto 不支持 X25519 Box
  • 密钥派生路径与 Happy 完全一致:确保两端互操作(L23 教训)
  • TypeScript as BufferSource 断言:TS 5.7 的 Uint8Array 类型不兼容 Web Crypto(L7 教训)