sovereignbase/cryptosuite

GitHub: sovereignbase/cryptosuite

一个跨 JS/TS 运行时、默认后量子安全的密码学工具包,通过声明式 API 提供加密通信、签名、密钥协商等核心能力。

Stars: 0 | Forks: 0

[![npm version](https://img.shields.io/npm/v/@sovereignbase/cryptosuite)](https://www.npmjs.com/package/@sovereignbase/cryptosuite) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/0632348993041607.svg)](https://github.com/sovereignbase/cryptosuite/actions/workflows/ci.yaml) [![codecov](https://codecov.io/gh/sovereignbase/cryptosuite/branch/master/graph/badge.svg)](https://codecov.io/gh/sovereignbase/cryptosuite) [![license](https://img.shields.io/npm/l/@sovereignbase/cryptosuite)](LICENSE) # cryptosuite JS/TS 运行时无关、量子安全且敏捷的密码学工具包,提供声明式 API,用于密码消息传递、消息认证、数字签名、密钥协商和标识符。 ## 兼容性 - 运行时:已在浏览器、bun、deno、node、edge-runtimes 上经过测试。 - 模块格式:ESM 或 CJS - 必需的全局变量/API:`crypto`、`crypto.subtle`、`crypto.getRandomValues` - 类型:捆绑的 `.d.ts` ## 目标 - 跨现代 JavaScript 和 TypeScript 环境的运行时无关性 - 默认具备后量子安全性 - 密码敏捷性,随着建议的演进,留有添加或替换算法的空间,同时保持已颁发密钥的向后兼容性 - 表达清晰密码学意图的声明式 API 接口 ## 当前算法 - 标识符:`SHA-384` 或 48 个随机字节,编码为固定长度的 base64url 字符串 - 密码消息传递:`AES-GCM-256` - 消息认证:`HMAC-SHA-256` - 密钥协商:`X25519-ML-KEM-768` - 数字签名:`Ed25519-ML-DSA-65` ## 安装 ``` npm install @sovereignbase/cryptosuite # 或 pnpm add @sovereignbase/cryptosuite # 或 yarn add @sovereignbase/cryptosuite # 或 bun add @sovereignbase/cryptosuite # 或 deno add jsr:@sovereignbase/cryptosuite # 或 vlt install jsr:@sovereignbase/cryptosuite ``` ## 使用方法 ### 标识符 ``` import { Cryptographic } from '@sovereignbase/cryptosuite' import { Bytes } from '@sovereignbase/bytecodec' const discoveryHook = Bytes.fromString('resource discovery hook') // Uint8Array const newResourceId = await Cryptographic.identifier.generate() // "64xb64urlchars..." const discoveryId = await Cryptographic.identifier.derive(discoveryHook) // "64xb64urlchars..." const ingressId = Cryptographic.identifier.validate(discoveryId) // "64xb64urlchars..." | false ``` ### 密码消息 ``` import { Cryptographic } from '@sovereignbase/cryptosuite' import { Bytes } from '@sovereignbase/bytecodec' const messageBytes = Bytes.fromString('hello world') // Uint8Array const cipherKey = await Cryptographic.cipherMessage.generateKey() // JsonWebKey const sourceKeyMaterial = Bytes.fromString('deterministic key source') // Uint8Array const salt = Bytes.fromString('deterministic salt source') // Uint8Array const { cipherKey } = await Cryptographic.cipherMessage.deriveKey( sourceKeyMaterial, { salt } ) // {cipherKey: JsonWebKey, salt: Uint8Array} const cipherMessage = await Cryptographic.cipherMessage.encrypt( cipherKey, messageBytes ) // {ciphertext: ArrayBuffer, iv: Uint8Array} const roundtrip = await Cryptographic.cipherMessage.decrypt( cipherKey, cipherMessage ) // Uint8Array const plainMessage = Bytes.toString(roundtrip) // 'hello world' ``` ### 消息认证 ``` import { Cryptographic } from '@sovereignbase/cryptosuite' import { Bytes } from '@sovereignbase/bytecodec' const messageBytes = Bytes.fromString('authenticated payload') // Uint8Array const generatedMessageAuthenticationKey = await Cryptographic.messageAuthentication.generateKey() // JsonWebKey const sourceKeyMaterial = Bytes.fromString('deterministic key source') // Uint8Array const salt = Bytes.fromString('deterministic salt source') // Uint8Array const { messageAuthenticationKey } = await Cryptographic.messageAuthentication.deriveKey(sourceKeyMaterial, { salt, }) // {messageAuthenticationKey: JsonWebKey, salt: Uint8Array} const tag = await Cryptographic.messageAuthentication.sign( generatedMessageAuthenticationKey, messageBytes ) // ArrayBuffer const verified = await Cryptographic.messageAuthentication.verify( generatedMessageAuthenticationKey, messageBytes, tag ) // boolean ``` ### 密钥协商 ``` import { Cryptographic } from '@sovereignbase/cryptosuite' import { Bytes } from '@sovereignbase/bytecodec' const sourceKeyMaterial = Bytes.fromString('k'.repeat(32)) // Uint8Array, exactly 32 bytes const { encapsulateKey, decapsulateKey } = await Cryptographic.keyAgreement.generateKeypair() // {encapsulateKey: JsonWebKey, decapsulateKey: JsonWebKey} const deterministicKeypair = await Cryptographic.keyAgreement.deriveKeypair(sourceKeyMaterial) // {encapsulateKey: JsonWebKey, decapsulateKey: JsonWebKey} const { keyOffer, cipherKey: senderCipherKey } = await Cryptographic.keyAgreement.encapsulate(encapsulateKey) // {keyOffer: {ciphertext: ArrayBuffer}, cipherKey: JsonWebKey} const { cipherKey: receiverCipherKey } = await Cryptographic.keyAgreement.decapsulate(keyOffer, decapsulateKey) // {cipherKey: JsonWebKey} ``` ### 数字签名 ``` import { Cryptographic } from '@sovereignbase/cryptosuite' import { Bytes } from '@sovereignbase/bytecodec' const sourceKeyMaterial = Bytes.fromString('s'.repeat(64)) // Uint8Array, exactly 64 bytes const bytes = Bytes.fromString('signed payload') // Uint8Array const { signKey, verifyKey } = await Cryptographic.digitalSignature.generateKeypair() // {signKey: JsonWebKey, verifyKey: JsonWebKey} const deterministicKeypair = await Cryptographic.digitalSignature.deriveKeypair(sourceKeyMaterial) // {signKey: JsonWebKey, verifyKey: JsonWebKey} const signature = await Cryptographic.digitalSignature.sign(signKey, bytes) // Uint8Array const verified = await Cryptographic.digitalSignature.verify( verifyKey, bytes, signature ) // boolean ``` ## 运行时行为 - `identifier.generate()` 需要 `crypto.getRandomValues` - 对称操作使用 WebCrypto - 密钥协商和数字签名使用 `noble` 混合原语 - 不支持的密码原语会抛出类型化的 `CryptosuiteError` 错误码 ## 安全提示 - `AES-GCM` 为每个密文提供机密性和消息完整性 - 在协议层验证对等方和会话设置 - 切勿重复使用 `(key, iv)` 对 - 将 JWK 和派生密钥材料视为机密 - 签名应为规范的字节表示,而不是结构松散的对象 ## 测试 最新一次本地 `npm run test` 运行于 `2026-04-17`,Node 版本为 `v22.14.0 (win32 x64)`: - `65/65` 项测试通过 - 语句、分支、函数和行的覆盖率达到了 `100%` - 端到端运行时套件全部通过,包括: - Node ESM - Node CJS - Bun ESM - Bun CJS - Deno ESM - Edge Runtime ESM - Cloudflare Workers ESM - Chromium - Firefox - WebKit - Mobile Chrome 仿真 - Mobile Safari 仿真 - 该运行时套件目前针对每个运行时执行了 `20/20` 个公共 API 场景: - 1 项静态连接检查 - 19 个公共方法 ## 基准测试 最新一次本地 `npm run bench` 运行于 `2026-04-17`,Node 版本为 `v22.14.0 (win32 x64)`。 | 基准测试名称 | 操作次数 | 总耗时 (ms) | 平均耗时 (ms/op) | 每秒操作数 (ops/sec) | | ----------------------------------- | --: | ------: | ------: | --------: | | `identifier.generate` | 100 | 2.91 | 0.0291 | 34389.08 | | `identifier.derive` | 100 | 34.97 | 0.3497 | 2859.53 | | `identifier.validate` | 100 | 0.41 | 0.0041 | 243961.94 | | `cipherMessage.generateKey` | 100 | 48.77 | 0.4877 | 2050.38 | | `cipherMessage.deriveKey` | 100 | 67.84 | 0.6784 | 1474.02 | | `cipherMessage.encrypt` | 100 | 36.80 | 0.3680 | 2717.03 | | `cipherMessage.decrypt` | 100 | 36.02 | 0.3602 | 2776.57 | | `messageAuthentication.generateKey` | 100 | 44.84 | 0.4484 | 2230.24 | | `messageAuthentication.deriveKey` | 100 | 75.64 | 0.7564 | 1322.07 | | `messageAuthentication.sign` | 100 | 29.09 | 0.2909 | 3437.31 | | `messageAuthentication.verify` | 100 | 25.33 | 0.2533 | 3947.69 | | `keyAgreement.generateKeypair` | 100 | 827.02 | 8.2702 | 120.92 | | `keyAgreement.deriveKeypair` | 100 | 842.11 | 8.4211 | 118.75 | | `keyAgreement.encapsulate` | 100 | 1669.17 | 16.6917 | 59.91 | | `keyAgreement.decapsulate` | 100 | 1240.95 | 12.4095 | 80.58 | | `digitalSignature.generateKeypair` | 100 | 808.57 | 8.0857 | 123.67 | | `digitalSignature.deriveKeypair` | 100 | 612.56 | 6.1256 | 163.25 | | `digitalSignature.sign` | 100 | 3478.93 | 34.7893 | 28.74 | | `digitalSignature.verify` | 100 | 2574.33 | 25.7433 | 38.85 | 结果因机器和 Node 版本而异。 ## 致谢 后量子原语构建于 [noble](https://paulmillr.com/noble/) 之上。 感谢 Paul Miller 提供了这个异常清晰、工程出色且真正令人惊叹的项目。 ## 许可证 Apache-2.0
标签:AES-GCM-256, Browser, Bun, CMS安全, CVE, Deno, Ed25519-ML-DSA-65, GNU通用公共许可证, HMAC-SHA-256, JavaScript, JSONLines, Node.js, NPM包, OSV-Scalibr, TypeScript, WebCrypto, X25519-ML-KEM-768, 前端加密, 加密工具包, 加密敏捷性, 加密消息传输, 后端加密, 后量子密码学, 哈希算法, 声明式API, 安全插件, 密码学, 密钥协商, 手动系统调用, 抗量子计算, 数字签名, 数据可视化, 本体建模, 消息认证, 端到端加密, 网络安全, 自定义脚本, 跨运行时, 防御绕过, 隐私保护, 零信任