SM9 标识密码算法
SM9 标识密码算法
SM9 使用身份字符串参与密钥派生和密码运算。GMKit 当前只通过 Java 制品 cn.gmkit:gmkit-sm9:0.10.1 提供签名、验签、基于身份的加密(IBE)、PEM 和流式签名;底层由 JNI 调用随 JAR 分发的 GmSSL 本地动态库。gmkitx 不提供 SM9、WASM 占位或浏览器降级实现。
采用前先回答五个问题
SM9 的接入成本主要来自密钥基础设施、身份治理、对端生态和本地动态库运维。是否采用应依据协议要求和部署条件评估,不应只因 API 可以调用就引入。
身份与密钥角色
身份按 UTF-8 原样转换。首尾空格会进入身份字节,全空白身份会被拒绝;派生、验签和 IBE 两端必须使用完全相同的字节。中文、emoji 和非 BMP 字符由 Java/JNI 测试覆盖,业务协议仍应明确 Unicode 规范化策略。
功能和数据边界
签名或加密结果含随机性,不应把一次随机输出写成固定标准向量。测试应检查成功、错误身份、篡改消息、篡改签名或密文,以及资源关闭后的失败行为。
大数据采用混合加密
IBE 的 255 字节上限适合保护短会话材料,不适合直接处理文件或长业务报文。大数据流程应明确分层:
- 生成随机 16 字节 SM4 会话 key。
- 使用 SM4-GCM 或 CCM 认证加密业务数据。
- 使用接收方身份和 SM9 公开主密钥保护会话 key。
- 在载荷中记录版本、身份、SM4 mode、nonce、AAD、ciphertext、tag 和 SM9 密文编码。
这里描述的是协议构成,不是稳定序列化格式。调用方需要定义字段顺序、长度、编码和升级规则。
受支持平台
单个 JAR 包含五组 runtime,启动时只解压和加载当前平台资源:
其他 OS/CPU 组合返回不支持错误,不会自动改用纯 Java 或其他算法。正式环境应在启动阶段检查可用性、平台标识和加载错误;测试环境要求 SM9 时,isAvailable() == false 必须使测试失败,不能计为成功跳过。
句柄与 PEM 边界
- 主密钥、用户私钥和签名上下文持有 native handle,使用 try-with-resources;
close()可重复调用。 - 关闭后再次操作会抛
SM9Exception。不要把同一句柄交给多个都负责关闭它的组件。 - PEM 口令和路径按 UTF-8 处理;Windows native 使用宽字符文件 API。口令或路径包含 NUL 时拒绝。
- 公开主密钥可以分发,主私钥和用户私钥只能以受控方式保存;口令加密 PEM 不替代文件权限、密钥托管和审计。
验证证据
构建固定 GmSSL v3.1.1 commit d655c06b3a6b0fe8cff900f293bf0e5aac6eb0a2。三层测试回答不同问题,不能互相替代:
固定结果的可核查来源是锁定提交的 tests/sm9test.c。Java 公共 API 不暴露原始 ks/ke/ds/de 内存结构,因此标准派生向量在 GmSSL 层执行,Java 层专门验证公开 API 行为和边界。
完整可运行案例与测试对应关系见 Java SM9 API 说明书。