npm.io
0.10.1 • Published yesterday

gmkitx

Licence
Apache-2.0
Version
0.10.1
Deps
0
Size
501 kB
Vulns
0
Weekly
0
Stars
6

GMKitX

纯 TypeScript 国密算法工具集

NPM Version License TypeScript

特性概览安装指南快速上手API 参考


gmkitx 是一套纯 TypeScript 实现的密码学工具集,覆盖 SM2 / SM3 / SM4 / ZUC 等国密算法,并提供 SHA 系列国际摘要算法。当前包不包含 SM9,也不会在 TypeScript 侧包装 C、WASM 或 native runtime。 目标是提供一套同构(Isomorphic)的代码库,让开发者在 Node.js现代浏览器中使用一致的 API 进行加密、解密、签名与哈希运算。

核心特性

我们强调一致性可维护性并重:

  • 同构运行:一套代码无缝运行于 Node.js (>= 18) 与浏览器环境,无需 polyfill。
  • 双重范式:既支持 函数式(Functional) 调用,也保留 面向对象(OOP) 封装。
  • 互操作友好:支持常见密文格式与编码(Hex/Base64、C1C3C2/C1C2C3、ASN.1 DER)。
  • 按需加载:Tree-shaking 友好,可按算法模块引入。
  • 类型完整:内建 .d.ts 类型定义,编码即文档。

支持矩阵与边界

算法 TypeScript 当前范围 主要格式/参数 不支持或注意
SM2 密钥生成、加解密、签名/验签、密钥交换 C1C3C2 默认,可选 C1C2C3;签名支持 raw / der / auto;输入输出支持 hex/base64 SM2 加密有随机性,测试不固定完整密文;大数据建议 SM2 + SM4 混合加密
SM3 摘要、HMAC、流式更新 hex/base64 输出 无认证加密语义,仅用于摘要/MAC 组合
SM4 ECB / CBC / CTR / CFB / OFB / GCM / CCM PKCS7 / ZERO / NONE;AEAD 返回 ciphertext + tag ECB 不建议保护敏感数据;AEAD 必须保存并校验 tag
ZUC ZUC-128 密钥流、标准 EEA3 消息加密、EIA3 MAC;保留旧密钥流入口 key/iv 均为 16 字节;密钥流长度按字节,zucKeystreamWords 按 32-bit word 不支持 ZUC-256;ZUC 加密不自带完整性保护
SHA SHA-1/256/384/512 摘要 hex/base64 输出 SHA-1 仅用于兼容旧系统;当前不提供 SHA-224
SM9 不支持 TypeScript 侧没有 SM9,也不包装 native/WASM;如需 SM9,请使用 Java 侧 gmkit-sm9 JNI/GmSSL 模块

测试中的 ZUC、SM3、SM4 固定值是本项目 Java / TypeScript 两端对齐使用的项目向量;没有标注为外部标准向量的值,不应被当作标准测试向量来源。


安装与环境

环境要求:Node.js >= 18 或任意支持 ES6+ 的现代浏览器。

# npm
npm install gmkitx

# pnpm (推荐)
pnpm add gmkitx

# yarn
yarn add gmkitx

快速上手

风格一:函数式编程(推荐)

适合现代前端开发,利于 Tree-shaking,代码更简洁。

1) SM2 非对称加密 + 签名
import {
  sm2GenerateKeyPair,
  sm2Encrypt,
  sm2Decrypt,
  sm2Sign,
  sm2Verify,
  SM2CipherMode,
  InputFormat,
  OutputFormat,
} from 'gmkitx';

const { publicKey, privateKey } = sm2GenerateKeyPair();
const message = '订单明文';

// 加密 / 解密(显式指定密文模式,便于互操作)
const cipherText = sm2Encrypt(publicKey, message, {
  mode: SM2CipherMode.C1C3C2,
  outputFormat: OutputFormat.BASE64,
});
const plainText = sm2Decrypt(privateKey, cipherText, {
  mode: SM2CipherMode.C1C3C2,
  inputFormat: InputFormat.BASE64,
});

// 签名 / 验签
const signature = sm2Sign(privateKey, message);
const ok = sm2Verify(publicKey, message, signature);
2) SM3 摘要 + HMAC
import { sm3Digest, sm3Hmac, OutputFormat } from 'gmkitx';

const hexHash = sm3Digest('订单摘要'); // 默认 Hex
const base64Hash = sm3Digest('订单摘要', { outputFormat: OutputFormat.BASE64 });
const mac = sm3Hmac('sm3-secret', '订单摘要');
3) SM4 对称加密(CBC 示例)
import { sm4Encrypt, sm4Decrypt, CipherMode, PaddingMode, OutputFormat } from 'gmkitx';

const key = '0123456789abcdeffedcba9876543210'; // 128 位密钥(Hex)
const iv = 'fedcba98765432100123456789abcdef';  // 128 位 IV(Hex)

const sm4Payload = sm4Encrypt(key, '敏感数据', {
  mode: CipherMode.CBC,
  padding: PaddingMode.PKCS7,
  iv,
  outputFormat: OutputFormat.BASE64,
});
const plaintext = sm4Decrypt(key, sm4Payload, {
  mode: CipherMode.CBC,
  padding: PaddingMode.PKCS7,
  iv,
});
风格二:命名空间导入

结构清晰,适合大型项目统一管理加密模块。

import { sm2, sm3, sm4, sha, CipherMode, PaddingMode, SM2CipherMode } from 'gmkitx';

const { publicKey, privateKey } = sm2.generateKeyPair();
const key = '0123456789abcdeffedcba9876543210';
const iv = 'fedcba98765432100123456789abcdef';

// SM2
const cipher = sm2.encrypt(publicKey, '订单数据', { mode: SM2CipherMode.C1C3C2 });
const plain = sm2.decrypt(privateKey, cipher, { mode: SM2CipherMode.C1C3C2 });
const signature = sm2.sign(privateKey, '订单数据');
const verified = sm2.verify(publicKey, '订单数据', signature);

// SM3
const hash = sm3.digest('订单摘要');

// SM4
const sm4Result = sm4.encrypt(key, '敏感数据', {
  mode: CipherMode.CBC,
  padding: PaddingMode.PKCS7,
  iv,
});
const sm4Plain = sm4.decrypt(key, sm4Result, {
  mode: CipherMode.CBC,
  padding: PaddingMode.PKCS7,
  iv,
});

// SHA 国际标准
const sha512Hash = sha.sha512('Hello World');
风格三:浏览器脚本 (CDN)

通过 UMD 构建包,在 HTML 中直接使用全局变量 GMKit

<script src="https://unpkg.com/gmkitx@<version>/dist/index.global.js"></script>
<script>
  const actual = GMKit.sm3Digest('abc');
  const expected = '66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0';
  if (actual !== expected) throw new Error(`SM3 vector mismatch: ${actual}`);
</script>

<version> 替换为 npm 已发布的精确版本。不要在生产页面使用浮动 latest;预发布版本发布前,CDN URL 也不会存在。

推荐使用带算法前缀的顶层名称,例如 sm2Signsm3Digestsm2GenerateKeyPair。 旧的 signdigestgenerateKeyPair 等裸名继续导出以保证升级兼容,但已标记 @deprecated;新代码请使用前缀函数或 sm2 / sm3 命名空间。


当前兼容与安全边界

  • sm4Encrypt 现在返回 { ciphertext, tag?, format } 对象;sm4Decrypt 可直接接收该对象。
  • zucKeystream(key, iv, length)length 改为 字节数;若需要按 32-bit word,使用 zucKeystreamWords
  • sm2Encrypt 的模式参数改为选项对象:sm2Encrypt(pub, data, { mode });二进制解密使用 sm2DecryptBytes
  • sm2Sign / sm2Verify / signatureToXml 支持 signatureFormat: 'raw' | 'der' | 'auto';DER 输入请显式标注,解析器只接受 canonical DER。
  • Base64 密文解密支持自动识别;跨语言互操作时建议显式指定 inputFormat: InputFormat.BASE64(SM2 / SM4 / ZUC)。二进制明文分别使用 sm2DecryptBytessm4DecryptByteszucDecryptBytes,避免 UTF-8 解码破坏数据。
  • 安全修复:SM2 现在会拒绝非法 mode / signatureFormat;SM4 现在会拒绝奇数长度的 hex key/iv,并严格校验 GCM 标签长度。

API 深度指南

SM2(椭圆曲线公钥密码)
  • 加/解密、签名/验签、密钥对生成;默认 C1C3C2,可切换 C1C2C3
  • Node/浏览器同构,面向对象与函数式并行。
  • 公钥输入支持非压缩格式 04 || x || y(65 字节 / 130 hex)与压缩格式 02/03 || x(33 字节 / 66 hex);加密输出中的 C1 当前为非压缩点。
  • 解密支持 raw C1C3C2 / C1C2C3,也支持 canonical ASN.1 DER 密文;BER、非最短编码和尾随数据会拒绝。未显式传 mode 时会先按 C1C3C2 尝试,再按 C1C2C3 尝试。
  • 签名默认输出 raw r || s(64 字节 / 128 hex),可指定 DER;验签可指定 raw / der / auto。签名和验签必须使用相同 userId,默认 1234567812345678
import { SM2, SM2CipherMode, InputFormat, OutputFormat } from 'gmkitx';

const sm2 = SM2.fromPrivateKey(privateKey);
const signature = sm2.sign('核心指令');
const verified = sm2.verify('核心指令', signature);

const cipher = sm2.encrypt('数据', { mode: SM2CipherMode.C1C3C2 });
const plain = sm2.decrypt(cipher);

// DER + Base64 签名示例
const sigDer = sm2.sign('核心指令', { signatureFormat: 'der', outputFormat: OutputFormat.BASE64 });
const ok = sm2.verify('核心指令', sigDer, { signatureFormat: 'der', inputFormat: InputFormat.BASE64 });
SM3(消息摘要)
  • 流式更新,Hex/Base64 输出;与 SHA API 对齐。
import { SM3, OutputFormat } from 'gmkitx';

const sm3 = new SM3();
sm3.update('part-1');
sm3.update('part-2');

const hex = sm3.digest(); // 默认 Hex
const base64 = SM3.digest('part-1part-2', { outputFormat: OutputFormat.BASE64 });

实例 digest() 完成后会重置状态,便于复用同一个对象处理下一条消息。若同一消息需要两种编码,应对摘要字节统一编码,或像上例一样重新摘要;不能把第二次 digest() 当成第一次结果的另一种格式。

SM4(分组密码)
  • 支持 ECB | CBC | CTR | CFB | OFB | GCM | CCM,PKCS7/NoPadding 可选。
mode iv / nonce padding tag
ECB 不使用 PKCS7 / ZERO / NONE
CBC 16 字节 IV PKCS7 / ZERO / NONE
CTR / CFB / OFB 16 字节 IV 不使用分组填充,建议 NONE
GCM 12 字节 IV NONE 12-16 字节,默认 16;aad 必须与解密端一致
CCM 7-13 字节 nonce,建议 12 NONE 4-16 字节偶数,默认 16;aad 必须与解密端一致

sm4Encrypt 返回 { ciphertext, tag?, format };GCM/CCM 解密时需传入同一个 ivaadtag,或直接把加密结果对象传给 sm4Decrypt

import { SM4, sm4Encrypt, sm4Decrypt, CipherMode, PaddingMode } from 'gmkitx';

const key = '0123456789abcdeffedcba9876543210';
const sm4 = new SM4(key, { mode: CipherMode.GCM, padding: PaddingMode.NONE, iv: '00112233445566778899aabb' });

const result = sm4.encrypt('敏感信息');
const decrypted = sm4.decrypt(result);

// CCM(AEAD)示例:7-13 字节 nonce,支持 AAD
const ccm = sm4Encrypt(key, '敏感信息', { mode: CipherMode.CCM, iv: '00112233445566778899aabb', aad: 'meta', tagLength: 16 });
const ccmPlain = sm4Decrypt(key, ccm, { mode: CipherMode.CCM, iv: '00112233445566778899aabb', aad: 'meta' });
ZUC(祖冲之序列密码)
  • 覆盖 128-EEA3(机密性)与 128-EIA3(完整性);同一 key/IV 生成的密钥流绝不能跨消息复用。
  • 当前仅实现 ZUC-128,key 与 iv 都必须是 16 字节;zucEncrypt / zucDecrypt 每次都从 IV 起始生成密钥流。
  • zucDecrypt 将结果按 UTF-8 解码为字符串;二进制数据使用 zucDecryptBytes
  • eea3 是为旧调用方保留的 EEA3 密钥流入口;按 3GPP 位长度加密消息应使用 eea3Encrypt,完整性标签使用 eia3
import { zucEncrypt, zucDecryptBytes, zucKeystream, zucKeystreamWords } from 'gmkitx';

const cipher = zucEncrypt(key, iv, 'Hello ZUC');
const keystream = zucKeystream(key, iv, 32); // 32 bytes keystream
const wordStream = zucKeystreamWords(key, iv, 8); // 8 words
const binaryPlain = zucDecryptBytes(key, iv, cipher); // Uint8Array
SHA(国际标准摘要)
  • SHA1/256/384/512 系列,API 与 SM3 一致,便于混合使用。
import { sha } from 'gmkitx';

const hash = sha.sha256('Hello World');

算法选择与安全边界

  • 没有“又快又安全又通用”的单一加密方案,算法选择必须按场景做权衡。
  • 业务数据加密优先 SM4-GCMSM4-CCMCBC/CTR/CFB/OFB 仅提供机密性,不提供完整性认证,需额外 MAC。
  • SM2 适合密钥封装、签名验签,不适合直接加密大数据(建议 SM2 + SM4 混合加密)。
  • ZUC 更偏通信协议场景(如 EEA3/EIA3),通用业务通常优先 SM4。
  • SHA-1 仅用于兼容旧系统,不建议用于新系统安全场景。
  • SM9 当前不属于 TypeScript 包能力范围;本包不提供 C/WASM/native 包装。
Java 对接提示(重点)
  • Java PKCS5Padding 在 SM4(16 字节分组)场景下语义上对应前端/Node 的 PKCS7
  • Java/BouncyCastle 若使用 SM4/CCM/NoPadding,前端/Node 对应 mode: CipherMode.CCM;需显式对齐 nonce(7-13 字节)和 tag 长度。
  • SM2 签名格式要显式约定:Java 常见 DER,gmkitx 默认 raw。
  • Base64 密文解密支持自动识别;与 Java 等异构系统对接时建议显式传 inputFormat: InputFormat.BASE64(SM2 / SM4 / ZUC)。
  • 完整公开 API 清单与 Java 对照边界见 ../ts-docs/dev/API-SURFACE.zh-CN.md

编码与格式

InputFormat / OutputFormat 统一规范密文与签名的编码格式。

import { InputFormat, OutputFormat, sm2Encrypt, sm2Decrypt, sm4Encrypt, sm4Decrypt, CipherMode, PaddingMode } from 'gmkitx';

const sm2Cipher = sm2Encrypt(pubKey, 'hello', { outputFormat: OutputFormat.BASE64 });
const sm2Plain = sm2Decrypt(privKey, sm2Cipher, { inputFormat: InputFormat.BASE64 });

const sm4Result = sm4Encrypt(key, 'hello', { mode: CipherMode.ECB, padding: PaddingMode.PKCS7, outputFormat: OutputFormat.BASE64 });
const sm4Plain = sm4Decrypt(key, sm4Result, { mode: CipherMode.ECB, padding: PaddingMode.PKCS7 }); // 自动读取 result.format

小程序/受限环境提示

  • 若运行环境缺少 TextEncoder/TextDecoder,可使用 setTextCodec 注入自定义 UTF-8 编解码器。
  • 默认 RNG 策略为 warn:缺少 CSPRNG 时会警告并使用不安全兼容降级。安全环境使用 configureRNG('strict');受限平台通过 setCustomRNG 注入平台 CSPRNG。
  • 可通过 getEnvReport() 检查环境能力。

工具箱 (Utils)

gmkitx 暴露了底层的数据处理函数,方便处理编码转换与 ASN.1 结构。

分类 函数 说明
编码 hexToBytes, bytesToHex Hex 字符串与字节数组互转
编码 base64ToBytes, bytesToBase64 Base64 与字节数组互转
编码 stringToBytes, bytesToString UTF-8 字符串处理
编码 decodeInput, encodeOutput 输入/输出格式统一编解码
运算 xor, rotl 异或与循环左移
格式 rawToDer, derToRaw 签名的 RAW/DER 格式转换
随机 getRandomBytes, configureRNG, setCustomRNG 随机源与策略控制
环境 setTextCodec, getEnvReport 文本编解码与环境能力报告

工程审计命令

# 构建(含告警策略)
npm run build

# 类型检查
npm run type-check

# 单元测试
npm test

# 可运行示例:构建后用 Node 调用 dist
node -e "import('./dist/index.js').then(({ sm3Digest }) => console.log(sm3Digest('你好,国密')))"

# 发布包体积审计(npm pack dry-run)
npm run audit:pack

# 真实打包、临时安装并验证 ESM/CJS/IIFE 与旧兼容别名
npm run test:package

# 文档静态资源体积审计
npm run audit:docs:assets

许可证与第三方组件

gmkitx 自身按 Apache License 2.0 发布。发布构建内联了 @noble/curves@noble/hashes 的 MIT 代码,完整版权和许可证文本见 THIRD_PARTY_NOTICES.md,并随 npm tarball 一同分发。

Keywords