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

@tracer-kit/encryption-codec

v0.1.0

Published

AES-256-GCM and RSA-OAEP-SHA256 envelope encryption for browser diagnostics.

Readme

@tracer-kit/encryption-codec

npm install @tracer-kit/encryption-codec

模块角色

Encryption Codec 位于 Tracer Domain 与持久化层之间。宿主端使用公钥把规范化日志编码为加密信封,DevTools 扩展使用私钥解码。Core Storage 只保存信封,不接触明文和密钥语义。

flowchart LR
  Payload[规范化日志] --> AES[AES-256-GCM 加密]
  SessionKey[AES 会话密钥] --> AES
  PublicKey[RSA 公钥] --> Wrap[RSA-OAEP-SHA256 包装]
  SessionKey --> Wrap
  AES --> Envelope[EncryptedEnvelope]
  Wrap --> Envelope
  Envelope --> Storage[(Core Storage)]
  Envelope --> Unwrap[扩展私钥解包]
  PrivateKey[RSA 私钥] --> Unwrap
  Unwrap --> Decrypt[AES-GCM 解密]
  Envelope --> Decrypt
  Decrypt --> Plaintext[日志明文]

公共导出

  • createEncoder(publicJwk):导入 RSA 公钥并创建信封编码器。
  • createDecoder(privateJwk, options?):导入 RSA 私钥并创建信封解码器。
  • CRYPTO_SUITE:当前算法套件标识。
  • CodecError:携带稳定 code 的可识别信封格式错误。
  • 类型:EncryptedEnvelope、EnvelopeAuthenticationContext、EnvelopeEncoder、EnvelopeDecoder、CodecErrorCode。

内部的 Base64 和密钥导入辅助函数不从包入口导出。

信封格式

interface EncryptedEnvelopeV2 {
  // v2 使用记录 id 和 occurredAt 作为 AES-GCM AAD。
  formatVersion: 2;
  authenticatedData: 'storage-record-v1';
  // 固定算法套件:数据用 AES-GCM,加密数据密钥用 RSA-OAEP-SHA256。
  cryptoSuite: 'AES-256-GCM+RSA-OAEP-SHA256';
  // 被 RSA 公钥包装后的 AES 会话密钥,使用 Base64 编码。
  encryptedDataKey: string;
  // 每条记录独立生成的 12 字节 AES-GCM nonce,使用 Base64 编码。
  nonce: string;
  // AES-GCM 密文及认证标签,使用 Base64 编码。
  ciphertext: string;
}
import { createDecoder, createEncoder } from '@tracer-kit/encryption-codec';

// 宿主端只持有公钥,用于创建加密器。
const encoder = await createEncoder(publicJwk);
const context = { id: 'record-id', occurredAt: Date.now() };
const envelope = await encoder.encode(normalizedPayload, context);

// 私钥只允许存在于受控的 DevTools Service Worker 中。
const decoder = await createDecoder(privateJwk, {
  // 最多缓存 64 个已解包的 AES key;设为 0 可关闭缓存。
  cacheSize: 64,
});
const payload = await decoder.decode<LogPayload>(envelope, context);

内部实现

编码器创建时生成一个 AES-256-GCM 会话密钥,再用 RSA-OAEP-SHA256 公钥包装 AES 密钥。每条记录生成独立 12 字节 nonce,并用 AES-GCM 加密 JSON 明文。v2 同时把记录 id 和 occurredAt 编码为附加认证数据,字段仍可查询但无法在不触发认证失败的情况下被篡改。这样大数据由对称加密处理,RSA 只处理固定长度密钥。

解码器先校验信封版本、算法套件、Base64 字段和 nonce 长度,再用私钥解包 AES 密钥。解包结果按 encryptedDataKey 缓存在有界 LRU 中,避免同一编码器产生的多条记录反复执行 RSA 解密。

sequenceDiagram
  participant D as Decoder
  participant C as AES Key LRU
  participant R as RSA-OAEP
  participant A as AES-GCM
  D->>D: 校验版本、套件、Base64、nonce
  D->>C: 查找 encryptedDataKey
  alt 缓存未命中
    D->>R: 私钥解包 AES key
    R-->>D: raw AES key
    D->>C: 写入并淘汰最旧项
  else 缓存命中
    C-->>D: AES key
    D->>C: 移动到 LRU 队尾
  end
  D->>A: 认证解密 ciphertext
  A-->>D: JSON 明文

失败与安全边界

  • 公钥可进入宿主构建;私钥只在扩展运行时导入到受控 Worker/Service Worker,不进入任何构建产物。
  • 不支持的信封版本、非法 Base64 和 nonce 长度通过 CodecError 的 ENVELOPE_FORMAT_INVALID 稳定标识;认证失败或错误密钥仍拒绝解码。
  • 新写入使用 v2;Decoder 保留 v1 读取兼容,便于升级后读取历史记录。直接调用 Codec 时不传 context 仍会生成 v1,仅建议用于与持久化元数据无关的数据。
  • nonce 每条记录随机生成,不得复用或改为可预测值。

测试与维护

  • test/codec.test.ts:加解密往返、随机 nonce 和错误信封。
  • test/decoder-cache.test.ts:解码密钥 LRU 行为。

修改信封字段或算法套件时,必须同步本 README、两端调用者、测试以及 docs/modules/encryption-codec.md。