更新记录

0.1.0(2026-10-24) 下载此版本

首个未发布版本(插件版本统一 0.1.0),对齐 sm-crypto 0.5.7 全量字符串 API。

  • H5:utssdk/web/index.uts + sm-crypto 0.5.7 ESM vendor;全量 sm2/sm3/sm4。
  • Android:utssdk/app-android Kotlin 原生(BigInteger + SecureRandom),蒸汽模式通过 uts-proxy 调用。
  • iOS:utssdk/app-ios Swift + 内置 BigInt 5.7.0(不走 SPM),x86_64 模拟器已验证。
  • 微信小程序:utssdk/mp-weixin 全量入口 + rng-shim.js(wx.getRandomValues 异步预取 + 同步 crypto 垫片)+ sm-crypto.mp.js(rng 懒初始化)。
  • vendor 重新打包:sm-crypto.esm.js / sm-crypto.mp.js 中 jsbn 1.1.0 全部内联,不再包含 node_modules 字样/模块 key;保留 upstream MIT 头。
  • 验证:H5 e2e 26 passed;Android 真机 uts-proxy 全 API 日志;iOS 473 项对拍 + 模拟器全 API 日志;mp DevTools 3.17.4 + Node 模拟全 API。
  • 修复:pages.json privacy 页 backgroundColor/backgroundColorContent: transparent(非法 hexColor)→ #FFFFFF。
  • 限制:sm4 output='array' 未支持;sm2GetPoint 的 k/x1 为 hex 字符串;签名 pointPool 未支持;HarmonyOS 未实现。

平台兼容性

uni-app x(5.26)

Chrome Chrome插件版本 Safari Safari插件版本 Android Android插件版本 iOS iOS插件版本 鸿蒙 微信小程序 微信小程序插件版本
80 0.1.0 12 0.1.0 6.0 0.1.0 14 0.1.0 - 2.25.3 0.1.0

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × × √

sm-crypto-x

国密 SM2 加密的 uni_modules 封装,已对齐 sm-crypto 0.5.7:

  • H5:utssdk/web/index.uts 使用 sm-crypto 0.5.7 的 ESM vendor。
  • Android(蒸汽模式 / 原生引擎):utssdk/app-android 使用 Kotlin 原生实现(java.math.BigInteger + java.security.SecureRandom),按 0.5.7 doEncrypt 语义移植。
  • iOS(原生引擎):utssdk/app-ios 使用 Swift + 内置 BigInt 5.7.0,按 0.5.7 doEncrypt 语义移植。

插件只负责「给定公钥做 SM2 加密」,不内置任何业务公钥;公钥由调用方(项目侧)持有并传入。

命名:sm-crypto-x = 上游 sm-crypto + uni-app x 适配后缀;目录名与 package.json 的 id 一致。它是本项目维护的 uni_modules 封装,不是上游 sm-crypto 的官方 x 版本;发布到插件市场前请确认不会与上游混淆。

用法

import { sm2Encrypt } from '@/uni_modules/sm-crypto-x'

const PUBLIC_KEY = '04...' // 04 开头,130 位十六进制
const cipherText = sm2Encrypt('123456', PUBLIC_KEY)       // 默认 cipherMode = 1(C1C3C2)
const cipherText2 = sm2Encrypt('123456', PUBLIC_KEY, 0)   // 0 = C1C2C3

导入只写到插件根目录,不要写成 @/uni_modules/sm-crypto-x/utssdk/...(uni_modules 规范只允许导入插件根目录)。

平台边界

平台 状态 说明
H5(Chrome) 已验证(全量 API) utssdk/web/index.uts + sm-crypto 0.5.7;e2e 26 passed;浏览器实测 sm2 密钥对/加解密/签名验签、sm3、sm4 全通过
Android(蒸汽模式,App 逻辑层走 JS 引擎) 全量 API 运行时验证通过 没有 app-js;uts-proxy 调 app-android Kotlin 原生。真机日志 SM2_API_CHECK 130/64/128/true/123456/66c7…、SM4_API_CHECK db0669…/hello;全量编译成功
Android(原生引擎,非蒸汽模式) 全量 API 对拍 + 模块编译通过 Kotlin + BigInteger + SecureRandom;JVM 与 0.5.7 双向对拍;cli compile app-android --uni_module 通过;整机登录未单测
iOS(原生引擎) 全量 API 运行时验证通过(x86_64 模拟器) Swift + 内置 BigInt 5.7.0;473 项与 0.5.7 对拍;framework 编译通过;模拟器日志 SM2_API_CHECK 130/64/128/true/123456/66c7…、SM4_API_CHECK db0669…/hello。arm64 模拟器标准基座不支持,需 x86_64 或自定义基座
HarmonyOS(原生引擎) 未实现 没有 app-harmony 实现;插件清单标 -
微信小程序 已验证(DevTools 3.17.4) utssdk/mp-weixin/index.uts 全量 API;rng-shim.js 用 wx.getRandomValues 异步预取 32 字节,安装同步 globalThis.crypto 垫片;实测立即调用报 SM2_RNG_NOT_READY,800ms 后加密成功(len 208);编译 16 页

API 现状:H5、Android、iOS、微信小程序均已暴露 0.5.7 全量字符串 API(小程序 RNG 通过异步种子 + 同步垫片实现)。

蒸汽模式由 manifest.json 的 uni-app-x.vapor 开启:

  • 开启:Android 无 app-js → uts-proxy 走 app-android Kotlin 原生。
  • 关闭:Android 走 app-android;iOS 走 app-ios。
  • Harmony 原生引擎目前没有实现,仍需补 app-harmony。

uni_modules 只是包格式,不等于“全平台实现”。当前是 H5 JS 0.5.7 + Android/iOS 原生;HarmonyOS 尚未覆盖。

Android 原生实现

  • 文件:utssdk/app-android/Sm2Native.kt + utssdk/app-android/index.uts。
  • 随机数:java.security.SecureRandom(CSPRNG),不依赖 App JS 引擎的 crypto.getRandomValues。
  • 输出:与 sm-crypto 0.5.7 一致的 C1C3C2 / C1C2C3 十六进制串(C1 不带 04 前缀)。
  • 全量 API:sm2Decrypt、密钥对、getPublicKeyFromPrivateKey、压缩/比较/验公钥、签名验签、getPoint、sm3(HMAC)、sm4(ECB/CBC、pkcs#7/none)。
  • 对拍:Kotlin 加密/解密/签名/验签/HMAC/SM4 与 0.5.7 双向一致;签名覆盖 hash/der/userId 组合。
  • 蒸汽模式:没有 app-js,uts-proxy 调本模块;真机日志 SM2_API_CHECK 130/64/128/true/123456/66c7…、SM4_API_CHECK db0669…/hello,说明全量 API 已执行 Kotlin 原生。
  • 限制:sm4 的 output='array' 暂不支持(只返回 hex);sm2GetPoint 的 k/x1 以 hex 字符串返回。
  • 未验:完整登录流程未在本批重跑(代理调用已验,算法已对拍)。

iOS 原生实现

  • 文件:utssdk/app-ios/Sm2Native.swift + utssdk/app-ios/index.uts。
  • 随机数:SystemRandomNumberGenerator(系统 CSPRNG)。
  • BigInt:内置 attaswift/BigInt 5.7.0 源码(utssdk/app-ios/BigInt/,22 个 Swift 文件,MIT)。HBuilderX 5.26 的 SPM 依赖在本地 compile app-ios 报 Unable to resolve module dependency: 'BigInt',因此改为内置源码,不再走 SPM。
  • 对拍:Swift 与 0.5.7 双向 473 项(sm2 加解密两模式、密钥对/pub/compress/compare/verify、签名验签 hash×der×userId、DER 严格性、sm3 标准向量+HMAC、sm4 ECB/CBC/pkcs#7/pkcs#5/none)全部一致。
  • 编译:cli compile app-ios --uni_module sm-crypto-x 通过,生成 unimoduleSmCryptoX.framework。
  • 模拟器:x86_64 iPhone 13 Pro(iOS 15.5)运行通过;日志 SM2_API_CHECK 130/64/128/true/123456/66c7…、SM4_API_CHECK db0669…/hello。arm64 模拟器标准基座不支持(三方 SDK 缺 arm64 slice),需 x86_64 或自定义基座。
  • UTS 桥接:iOS UTS 不支持 Array.fromNative,generateKeyPair/getPoint 以逗号分隔字符串回传,UTS 侧 split 组装;密钥/x1 均为 hex,不含逗号。
  • 失败语义:Swift 侧非法公钥/异常返回空串或 false;sm4 output=array 打日志并返回空串,不抛异常。
  • 未验:iOS 真机。

微信小程序 RNG

  • appservice 实测(WeChat DevTools 3.17.4):globalThis.crypto === undefined,window === globalThis 且无 crypto;wx.getRandomValues 存在但为异步(约 2ms),无同步版本。
  • rng-shim.js 在模块加载即预取 32 字节 CSPRNG 种子,同步安装 globalThis.crypto.getRandomValues 垫片;种子未就绪时显式抛 SM2_RNG_NOT_READY,不回退 Math.random。
  • sm-crypto.mp.js 是 0.5.7 vendor 副本,唯一改动是把 rng 播种从模块求值改为首次取字节时懒初始化,避免登录页加载即崩。
  • 实测:加载后立即调用 → SM2_RNG_NOT_READY(页面不崩);800ms 后(用户输入后)→ 加密成功(len 208)。
  • pages.json 的 privacy 页 backgroundColor/backgroundColorContent 原为 transparent(非法 hexColor),会导致 DevTools 3.17.4 simulator launch failed;已改为 #FFFFFF。
  • 可选:登录前 await ensureSm2Ready();种子通常在用户点击前已就绪,非必需。

与上游 0.5.7 的对齐情况

项 本插件 上游 0.5.7
H5 JS 版本 0.5.7(esbuild ESM vendor) 0.5.7
Android 按 0.5.7 全量语义 Kotlin 移植 —
iOS 按 0.5.7 全量语义 Swift 移植 —
公开 API H5 / Android / iOS / mp:0.5.7 全量 sm2 密钥对/加解密/签名验签、sm3、sm4
RNG H5 用 window.crypto;App 用原生 CSPRNG;mp 用 wx.getRandomValues + 同步垫片 0.5.7 要求 crypto.getRandomValues
  • 0.5.7 的 crypto 依赖不再是 App 的阻塞点:App 不走 JS vendor,走 app-android / app-ios 原生 CSPRNG。
  • H5 在 HTTPS / localhost 下有 window.crypto,0.5.7 的 RNG 正常;e2e 登录已验证。
  • H5、Android、iOS、小程序均已暴露全量 API(含 sm2 签名验签、sm3、sm4)。
  • 小程序 appservice 没有 globalThis.crypto;rng-shim.js 用异步 wx.getRandomValues 预取 32 字节,安装同步 getRandomValues 垫片,种子未就绪时显式抛 SM2_RNG_NOT_READY,不回退 Math.random。
  • 0.5.7 的签名 hash 默认 true(0.4.0 起);使用签名 API 时需显式约定 hash 参数。

实现结构

sm-crypto-x/
├── package.json
├── readme.md
├── changelog.md
└── utssdk/
    ├── interface.uts           # 对外签名声明(仅类型,不在入口 runtime import)
    ├── web/index.uts           # H5 入口(sm-crypto 0.5.7 JS,全量 API)
    ├── mp-weixin/
    │   ├── index.uts           # 小程序入口(全量 API,走 rng-shim)
    │   ├── rng-shim.js         # wx.getRandomValues 异步预取 + 同步 crypto 垫片
    │   └── sm-crypto.mp.js     # 0.5.7 vendor 副本(rng 懒初始化)
    ├── app-android/
    │   ├── index.uts           # Android 原生入口(调 Sm2Native)
    │   └── Sm2Native.kt        # Kotlin SM2/SM3 实现 + SecureRandom
    ├── app-ios/
    │   ├── index.uts           # iOS 原生入口(调 Sm2Native)
    │   ├── config.json         # deploymentTarget 12.0(无 SPM 依赖)
    │   ├── Sm2Native.swift     # Swift SM2/SM3 实现 + SystemRandomNumberGenerator
    │   └── BigInt/             # attaswift/BigInt 5.7.0 源码(22 个 Swift 文件,MIT)
    └── sm-crypto.esm.js        # sm-crypto 0.5.7 + jsbn 1.1.0 的 ESM 产物(jsbn 已内联,勿手改)

没有 app-js 和根 index.uts:这样蒸汽模式在无 app-js 时会走 uts-proxy 到 app-android / app-ios 原生实现;H5 由 web/index.uts 命中。

interface.uts 只做签名声明,不在入口文件里 import:H5 的 Vite 会把类型导入解析成 ../interface(找不到 .uts)并 500。入口直接声明函数,签名保持与 interface.uts 一致。

许可证与归属

  • 本插件:MIT
  • 内置 sm-crypto.esm.js:MIT,来自 sm-crypto 0.5.7(JuneAndGreen)与 jsbn 1.1.0(Tom Wu / Andy Perlitch);jsbn 已整体内联,vendor 内无 node_modules 引用/模块 key
  • 插件版本:未发布,统一 0.1.0
  • Android Kotlin 实现:按 sm-crypto(MIT)的算法移植,保留 MIT 归属
  • iOS Swift 实现:按 sm-crypto(MIT)的算法移植;内置 attaswift/BigInt 5.7.0(MIT)
  • 该 JS 文件为构建产物(esbuild 0.20.1,--bundle --format=esm --platform=neutral),保留原始 MIT 头注释,请勿手工修改

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

许可协议

MIT License

Copyright (c) 2026 sm-crypto-x contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Third-party notices (all MIT):

  • sm-crypto 0.5.7 — Copyright © 2018 june01 https://github.com/JuneAndGreen/sm-crypto
  • jsbn 1.1.0 — Copyright (c) 2003-2005 Tom Wu, packaging by Andy Perlitch https://github.com/andyperlitch/jsbn
  • BigInt 5.7.0 — Copyright (c) 2016-2017 Károly Lőrentey https://github.com/attaswift/BigInt Full text: utssdk/app-ios/BigInt/LICENSE.md