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

@mijadesign/api-crypto

v0.1.0-beta.0

Published

Cross-runtime AES-256-GCM payload protocol for mobile clients

Readme

@mijadesign/api-crypto

跨运行时的 Payload AES-256-GCM 协议实现,兼容微信小程序、React Native 和 H5。

本包只负责协议和密码学操作,不负责获取、缓存或维护 kid/key,也不依赖 Taro、Axios、Fetch 或 React Native。调用方必须注入当前请求使用的 kid/key 和安全随机数实现。

第三方密码库 @noble/ciphers 是运行时依赖,构建产物不会内联该依赖。最终应用由自身构建工具决定如何将依赖放入终端产物。

协议

  • AES-256-GCM;
  • 12 字节随机 IV;
  • 16 字节认证 Tag;
  • Payload 格式为 {"ct":"<base64url>"}
  • AAD 格式为 v1|direction|METHOD|path|kid
  • GET/HEAD 只请求响应加密,其他请求加密 JSON Body。

运行时适配

  • 微信小程序注入 Taro.getRandomValues
  • React Native 注入经平台验证的安全随机数;
  • H5 注入 globalThis.crypto.getRandomValues

各调用方负责把自身网络库的 Header、Body 和 Response 映射为本包的无框架类型。

安装

pnpm add @mijadesign/api-crypto

@noble/ciphers 是本包的运行时依赖,会由包管理器安装;本包构建产物不会内联它。

基本用法

调用方必须自行提供当前有效的 kid/key。Key 必须是 32 字节 AES-256 密钥的 Base64URL 表示,不能使用普通字符串直接填入。

import {
  decryptCrypto,
  encryptCrypto,
  type cryptoKey,
  type RandomBytes,
} from '@mijadesign/api-crypto';

const key: cryptoKey = {
  kid: currentKid,
  keyB64url: currentKeyB64url,
};

const randomBytes: RandomBytes = async (length) => {
  // 使用当前运行时提供的安全随机数实现,不要使用 Math.random()
  return platformRandomBytes(length);
};

const prepared = await encryptCrypto({
  key,
  randomBytes,
  method: 'POST',
  url: '/mjsbtcloud/api/example/profile',
  body: { name: '张三' },
  headers: {
    Authorization: 'Bearer <access-token>',
  },
});

// 由调用方把 prepared.url、prepared.method、prepared.headers、prepared.body
// 映射到 Taro.request、Axios 或 fetch。
const rawResponse = await sendRequest(prepared);

const response = decryptCrypto(
  {
    status: rawResponse.status,
    headers: rawResponse.headers,
    body: rawResponse.body,
  },
  prepared.context,
);

const data = response.body;

encryptCrypto 对 GET/HEAD 请求只添加响应加密 Header,不修改请求 Body;其他请求会将 Body 序列化并替换为 {"ct":"..."}。解密必须在业务错误归一化之前执行,Axios 的 error.response 分支也需要经过同样的解密处理。

各运行时随机数示例

微信小程序

import Taro from '@tarojs/taro';

const randomBytes = async (length: number) => {
  const result = await Taro.getRandomValues({ length });
  const bytes = new Uint8Array(result.randomValues);
  if (bytes.length !== length) throw new Error('Taro.getRandomValues returned a wrong byte length');
  return bytes;
};

Web

const randomBytes = (length: number) => {
  const bytes = new Uint8Array(length);
  globalThis.crypto.getRandomValues(bytes);
  return bytes;
};

H5 必须运行在支持安全随机数的 HTTPS Secure Context 中。

React Native

RN 不应假设所有 Hermes 版本都提供 globalThis.crypto。请注入经过 iOS/Android 真机验证的安全随机数实现,例如由 Native 安全能力或经过验证的随机数模块提供:

const randomBytes = (length: number) => nativeSecureRandomBytes(length);

响应处理规则

  • 响应包含任意一个 X-Enc-* Header 时,必须校验完整的 Version、Kid、IV 并解密;
  • 加密请求收到成功的明文 2xx 响应会抛出 PLAINTEXT_SUCCESS_RESPONSE
  • 加密响应的认证失败会抛出 DECRYPT_FAILED
  • 明文非 2xx 响应且没有加密 Header 时,会原样返回给调用方处理登录失效或业务错误;
  • 不要捕获错误后自动切换到明文请求;
  • 不要记录 Key、明文 Body、解密后的敏感响应或完整密文。

API 适配建议

公共包不依赖网络库,适配层只需要完成以下映射:

| 网络库 | 请求映射 | 响应映射 | | --- | --- | --- | | Taro.request | 使用 prepared.method/url/headers/body | statusCode/header/data 映射为 status/headers/body | | Axios | 使用 prepared.method/url/headers/body | status/headers/data 映射为 status/headers/body | | fetch | 使用 prepared.method/url/headers/body | status/headers/text或json 映射为 status/headers/body |

上传、FormData、SSE 和二进制流不应直接套用本包的 JSON Payload 协议,需要使用各自的传输协议。