@boguang2000/gmcrypto
v1.0.7
Published
国密SM2、SM3、SM4算法组件,支持SM2公私钥对随机生成、SM2私钥计算生成公钥、SM2加密解密(密文支持字符串拼接模式和DER.ASN1模式)、SM2签名与验签(签名结果支持字符串拼接模式和DER.ASN1模式)、SM3摘要计算、SM4 ECB模式(支持PKCS7Padding和NoPadding)、SM4 CBC模式(支持PKCS7Padding和NoPadding)
Maintainers
Readme
gmcrypto-js
国密加密算法JavaScript实现库,全面支持SM2、SM3、SM4三种国密算法,提供完整的加密、解密、签名、验签和摘要计算功能。
一、组织说明
1.1、整体说明
gmcrypto-js是一个纯JavaScript实现的国密算法库,遵循《密码学算法国家/行业标准》,提供了丰富的API接口,支持多种数据格式输入输出,适用于需要国密算法支持的各类Web应用和Node.js服务。
1.2、兼容性说明
- 浏览器环境:支持所有现代浏览器,包括Chrome、Firefox、Safari、Edge等
- Node.js环境:支持Node.js 8.0及以上版本
- Java V8引擎:经过特殊优化,兼容Java V8引擎环境
- 模块系统:同时支持CommonJS、AMD和全局变量三种模块使用方式
- ES5兼容:生成的代码完全兼容ES5标准,确保在各种运行环境中稳定运行
1.3、功能特点
- SM2椭圆曲线密码算法:支持密钥生成、加密解密(字符串拼接模式和ASN1编码模式)、签名验签
- SM3密码杂凑算法:提供标准的摘要计算功能
- SM4分组密码算法:支持ECB和CBC两种工作模式
- 多数据格式支持:支持字符串、16进制字符串、字节数组三种数据格式的输入输出
- 工具函数库:提供完善的数据转换和辅助功能
1.4、使用方法
1.4.1、Node.js环境
通过npm安装:npm install @boguang2000/gmcrypto
// 引入库
const { Sm2Utils, Sm3Utils, Sm4Utils, CommonUtils, CipherMode } = require('@boguang2000/gmcrypto');
// 或引入文件
// const { Sm2Utils, Sm3Utils, Sm4Utils, CommonUtils, CipherMode } = require('../gmcrypto.min-1.0.7.js');1.4.2、浏览器环境
<!-- 引入版本 -->
<script src="path/to/gmcrypto.min-1.0.7.js"></script>
<script>
// 通过全局变量使用
const sm2Utils = new gmcrypto.Sm2Utils();
const hashResult = gmcrypto.Sm3Utils.encryptFromText('Hello, 国密!');
</script>二、API说明
2.1、CommonUtils工具类
CommonUtils提供了各种数据格式转换和辅助功能,是使用国密算法的基础工具集。
2.1.1、主要方法
| 方法名 | 描述 | 参数 | 返回值 |
|-------|------|------|-------|
| utf8StrToHex(str) | UTF8字符串转16进制字符串 | str: String - UTF8编码的字符串 | String - 16进制表示的字符串 |
| utf8StrToBytes(str) | UTF8字符串转字节数组 | str: String - UTF8编码的字符串 | Uint8Array/Array - 字节数组 |
| hexToBytes(hex) | 16进制字符串转字节数组 | hex: String - 16进制表示的字符串 | Uint8Array/Array - 字节数组 |
| hexToUtf8Str(hex) | 16进制字符串转UTF8字符串 | hex: String - 16进制表示的字符串 | String - UTF8编码的字符串 |
| bytesToHex(bytes) | 字节数组转16进制字符串 | bytes: Uint8Array/Array - 字节数组 | String - 16进制表示的字符串 |
| bytesToUtf8Str(bytes) | 字节数组转UTF8字符串 | bytes: Uint8Array/Array - 字节数组 | String - UTF8编码的字符串 |
| isHexString(hex) | 判断是否为有效的16进制字符串 | hex: String - 待判断的字符串 | Boolean - 是否为有效16进制字符串 |
| equals(a, b) | 比较两个值是否相等(适用于字符串、数组等) | a, b: 任意类型 - 待比较的值 | Boolean - 是否相等 |
| randomHex(len) | 生成指定长度的随机16进制字符串 | len: Number - 长度 | String - 随机16进制字符串 |
| randomWord() | 生成随机字(Word) | 无 | Number - 随机数 |
2.1.2、使用示例
// 字符串转16进制
const hex = gmcrypto.CommonUtils.utf8StrToHex('Hello, 国密!');
console.log(hex); // 输出: 48656c6c6f2c20e59c8b...
// 16进制转字节数组
const bytes = gmcrypto.CommonUtils.hexToBytes(hex);
// 字节数组转字符串
const str = gmcrypto.CommonUtils.bytesToUtf8Str(bytes);2.2、CipherMode枚举
CipherMode定义了SM2加密算法的不同数据拼接模式,主要用于控制加密数据的组织结构。
2.2.1、枚举值
| 枚举值 | 值 | 描述 |
|-------|-----|------|
| CipherMode.C1C2C3 | 1 | SM2标准默认的拼接模式:C1(椭圆曲线点) + C2(密文数据) + C3(哈希值) |
| CipherMode.C1C3C2 | 2 | 非标准的拼接模式:C1(椭圆曲线点) + C3(哈希值) + C2(密文数据) |
2.2.2、使用示例
// 创建C1C3C2模式的SM2工具实例
const sm2Utils = new gmcrypto.Sm2Utils(CipherMode.C1C3C2);
// 使用该实例进行加密解密
const cipherText = sm2Utils.encryptFromText(pubKeyHex, plainText);2.3、Sm2Utils
Sm2Utils提供SM2非对称加密算法的完整功能,包括密钥生成、加密解密和签名验签。
2.3.1、构造函数
// 默认构造(使用C1C2C3模式)
const sm2Utils = new gmcrypto.Sm2Utils();
// 指定模式构造
const sm2UtilsC1C3C2 = new gmcrypto.Sm2Utils(CipherMode.C1C3C2);2.3.2、密钥管理
| 方法名 | 描述 | 参数 | 返回值 |
|-------|------|------|-------|
| generateKeyPair() | 生成SM2密钥对 | 无 | String[] - 依次包含prvkeyhex私钥16进制串、pubkeyhex公钥16进制串 |
| getPublicKey(prvkeyhex) | 根据私钥生成公钥 | prvkeyhex: String - 私钥的16进制表示 | String - 公钥的16进制表示 |
2.3.3、加密解密
| 方法名 | 描述 | 参数 | 返回值 |
|-------|------|------|-------|
| encryptFromText(pubkey, plaintext) | 加密字符串明文 | pubkey: String - 公钥的16进制表示plaintext: String - 待加密的字符串 | String - 密文的16进制表示 |
| encryptFromHex(pubkey, plainhex) | 加密16进制明文 | pubkey: String - 公钥的16进制表示plainhex: String - 待加密的16进制字符串 | String - 密文的16进制表示 |
| encryptFromData(pubkey, plaindata) | 加密字节数组明文 | pubkey: Uint8Array/Array - 公钥的字节数组plaindata: Uint8Array/Array - 待加密的字节数组 | Uint8Array/Array - 密文的字节数组 |
| decryptToText(prvkey, ciphertext) | 解密到字符串 | prvkey: String - 私钥的16进制表示ciphertext: String - 密文的16进制表示 | String - 解密后的字符串 |
| decryptToHex(prvkey, cipherhex) | 解密到16进制字符串 | prvkey: String - 私钥的16进制表示cipherhex: String - 密文的16进制表示 | String - 解密后的16进制字符串 |
| decryptToData(prvkey, cipherdata) | 解密到字节数组 | prvkey: Uint8Array/Array - 私钥的字节数组cipherdata: Uint8Array/Array - 密文的字节数组 | Uint8Array/Array - 解密后的字节数组 |
| encryptASN1FromText(pubkey, plaintext) | ASN1模式加密字符串 | pubkey: String - 公钥的16进制表示plaintext: String - 待加密的字符串 | String - 密文的16进制表示 |
| encryptASN1FromHex(pubkey, plainhex) | ASN1模式加密16进制 | pubkey: String - 公钥的16进制表示plainhex: String - 待加密的16进制字符串 | String - 密文的16进制表示 |
| encryptASN1FromData(pubkey, plaindata) | ASN1模式加密字节数组 | pubkey: Uint8Array/Array - 公钥的字节数组plaindata: Uint8Array/Array - 待加密的字节数组 | Uint8Array/Array - 密文的字节数组 |
| decryptASN1ToText(prvkey, ciphertext) | ASN1模式解密到字符串 | prvkey: String - 私钥的16进制表示ciphertext: String - 密文的16进制表示 | String - 解密后的字符串 |
| decryptASN1ToHex(prvkey, cipherhex) | ASN1模式解密到16进制 | prvkey: String - 私钥的16进制表示cipherhex: String - 密文的16进制表示 | String - 解密后的16进制字符串 |
| decryptASN1ToData(prvkey, cipherdata) | ASN1模式解密到字节数组 | prvkey: Uint8Array/Array - 私钥的字节数组cipherdata: Uint8Array/Array - 密文的字节数组 | Uint8Array/Array - 解密后的字节数组 |
2.3.4、签名验签
| 方法名 | 描述 | 参数 | 返回值 |
|-------|------|------|-------|
| signFromText(prvkey, message) | 对字符串消息签名 | prvkey: String - 私钥的16进制表示message: String - 待签名的字符串 | String - 签名的16进制表示 |
| signFromHex(prvkey, messageHex) | 对16进制消息签名 | prvkey: String - 私钥的16进制表示messageHex: String - 待签名的16进制字符串 | String - 签名的16进制表示 |
| signFromData(prvkey, messageData) | 对字节数组消息签名 | prvkey: Uint8Array/Array - 私钥的字节数组messageData: Uint8Array/Array - 待签名的字节数组 | Uint8Array/Array - 签名的字节数组 |
| verifySignFromText(pubkey, message, sign) | 验证字符串消息签名 | pubkey: String - 公钥的16进制表示message: String - 原始消息字符串sign: String - 签名的16进制表示 | Boolean - 验签是否通过 |
| verifySignFromHex(pubkey, messageHex, sign) | 验证16进制消息签名 | pubkey: String - 公钥的16进制表示messageHex: String - 原始消息的16进制字符串sign: String - 签名的16进制表示 | Boolean - 验签是否通过 |
| verifySignFromData(pubkey, messageData, signData) | 验证字节数组消息签名 | pubkey: Uint8Array/Array - 公钥的字节数组messageData: Uint8Array/Array - 原始消息的字节数组signData: Uint8Array/Array - 签名的字节数组 | Boolean - 验签是否通过 |
| signASN1FromText(prvkey, message) | ASN1模式对字符串签名 | prvkey: String - 私钥的16进制表示message: String - 待签名的字符串 | String - 签名的16进制表示 |
| signASN1FromHex(prvkey, messageHex) | ASN1模式对16进制签名 | prvkey: String - 私钥的16进制表示messageHex: String - 待签名的16进制字符串 | String - 签名的16进制表示 |
| signASN1FromData(prvkey, messageData) | ASN1模式对字节数组签名 | prvkey: Uint8Array/Array - 私钥的字节数组messageData: Uint8Array/Array - 待签名的字节数组 | Uint8Array/Array - 签名的字节数组 |
| verifySignASN1FromText(pubkey, message, sign) | ASN1模式验证字符串签名 | pubkey: String - 公钥的16进制表示message: String - 原始消息字符串sign: String - 签名的16进制表示 | Boolean - 验签是否通过 |
| verifySignASN1FromHex(pubkey, messageHex, sign) | ASN1模式验证16进制签名 | pubkey: String - 公钥的16进制表示messageHex: String - 原始消息的16进制字符串sign: String - 签名的16进制表示 | Boolean - 验签是否通过 |
| verifySignASN1FromData(pubkey, messageData, signData) | ASN1模式验证字节数组签名 | pubkey: Uint8Array/Array - 公钥的字节数组messageData: Uint8Array/Array - 原始消息的字节数组signData: Uint8Array/Array - 签名的字节数组 | Boolean - 验签是否通过 |
2.3.5、使用示例
// 生成密钥对
const sm2Utils = new gmcrypto.Sm2Utils();
const keyPair = sm2Utils.generateKeyPair();
const { pubkeyhex, prvkeyhex } = keyPair;
// 加密解密示例(字符串拼接模式)
const plainText = 'Hello, 国密!';
const cipherText = sm2Utils.encryptFromText(pubkeyhex, plainText);
const decryptedText = sm2Utils.decryptToText(prvkeyhex, cipherText);
console.log(decryptedText === plainText); // true
// 签名验签示例
const sign = sm2Utils.signFromText(prvkeyhex, plainText);
const isValid = sm2Utils.verifySignFromText(pubkeyhex, plainText, sign);
console.log(isValid); // true
// ASN1模式示例
const cipherASN1 = sm2Utils.encryptASN1FromText(pubkeyhex, plainText);
const decryptedASN1 = sm2Utils.decryptASN1ToText(prvkeyhex, cipherASN1);2.4、Sm3Utils
Sm3Utils提供SM3密码杂凑算法的摘要计算功能,生成固定长度(256位)的哈希值。
2.4.1、主要方法
| 方法名 | 描述 | 参数 | 返回值 |
|-------|------|------|-------|
| encryptFromText(text) | 计算字符串的SM3摘要 | text: String - 待计算的字符串 | String - 64位16进制表示的哈希值 |
| encryptFromHex(hex) | 计算16进制字符串的SM3摘要 | hex: String - 待计算的16进制字符串 | String - 64位16进制表示的哈希值 |
| encryptFromData(data) | 计算字节数组的SM3摘要 | data: Uint8Array/Array - 待计算的字节数组 | Uint8Array/Array - 32字节的哈希值数组 |
2.4.2、使用示例
// 计算字符串的SM3摘要
const hashHex = gmcrypto.Sm3Utils.encryptFromText('Hello, 国密!');
console.log(hashHex); // 输出64位16进制字符串
console.log(hashHex.length); // 64
// 计算字节数组的SM3摘要
const bytes = gmcrypto.CommonUtils.utf8StrToBytes('Hello, 国密!');
const hashBytes = Sm3Utils.encryptFromData(bytes);
console.log(hashBytes.length); // 322.5、Sm4Utils
Sm4Utils提供SM4分组密码算法的加密解密功能,支持ECB和CBC两种工作模式。
2.5.1、加密方法
| 方法名 | 描述 | 参数 | 返回值 |
|-------|------|------|-------|
| gmcrypto.Sm4Utils.ECB.encryptFromText(plaintext, key) | 加密字符串明文(ECB模式) | plaintext: String - 待加密的字符串key: String - 密钥的16进制表示(16字节) | String - 密文的16进制表示 |
| gmcrypto.Sm4Utils.ECB.encryptFromHex(plainhex, key) | 加密16进制明文(ECB模式) | plainhex: String - 待加密的16进制字符串key: String - 密钥的16进制表示(16字节) | String - 密文的16进制表示 |
| gmcrypto.Sm4Utils.ECB.encryptFromData(plaindata, key) | 加密字节数组明文(ECB模式) | plaindata: Uint8Array/Array - 待加密的字节数组key: Uint8Array/Array - 密钥的字节数组(16字节) | Uint8Array/Array - 密文的字节数组 |
| gmcrypto.Sm4Utils.ECB.decryptToText(ciphertext, key) | 解密到字符串(ECB模式) | ciphertext: String - 密文的16进制表示key: String - 密钥的16进制表示(16字节) | String - 解密后的字符串 |
| gmcrypto.Sm4Utils.ECB.decryptToHex(cipherhex, key) | 解密到16进制字符串(ECB模式) | cipherhex: String - 密文的16进制表示key: String - 密钥的16进制表示(16字节) | String - 解密后的16进制字符串 |
| gmcrypto.Sm4Utils.ECB.decryptToData(cipherdata, key) | 解密到字节数组(ECB模式) | cipherdata: Uint8Array/Array - 密文的字节数组key: Uint8Array/Array - 密钥的字节数组(16字节) | Uint8Array/Array - 解密后的字节数组 |
| gmcrypto.Sm4Utils.CBC.encryptFromText(plaintext, key, iv) | 加密字符串明文(CBC模式) | plaintext: String - 待加密的字符串key: String - 密钥的16进制表示(16字节)iv: String - 初始向量的16进制表示(16字节) | String - 密文的16进制表示 |
| gmcrypto.Sm4Utils.CBC.encryptFromHex(plainhex, key, iv) | 加密16进制明文(CBC模式) | plainhex: String - 待加密的16进制字符串key: String - 密钥的16进制表示(16字节)iv: String - 初始向量的16进制表示(16字节) | String - 密文的16进制表示 |
| gmcrypto.Sm4Utils.CBC.encryptFromData(plaindata, key, iv) | 加密字节数组明文(CBC模式) | plaindata: Uint8Array/Array - 待加密的字节数组key: Uint8Array/Array - 密钥的字节数组(16字节)iv: Uint8Array/Array - 初始向量的字节数组(16字节) | Uint8Array/Array - 密文的字节数组 |
| gmcrypto.Sm4Utils.CBC.decryptToText(ciphertext, key, iv) | 解密到字符串(CBC模式) | ciphertext: String - 密文的16进制表示key: String - 密钥的16进制表示(16字节)iv: String - 初始向量的16进制表示(16字节) | String - 解密后的字符串 |
| gmcrypto.Sm4Utils.CBC.decryptToHex(cipherhex, key, iv) | 解密到16进制字符串(CBC模式) | cipherhex: String - 密文的16进制表示key: String - 密钥的16进制表示(16字节)iv: String - 初始向量的16进制表示(16字节) | String - 解密后的16进制字符串 |
| gmcrypto.Sm4Utils.CBC.decryptToData(cipherdata, key, iv) | 解密到字节数组(CBC模式) | cipherdata: Uint8Array/Array - 密文的字节数组key: Uint8Array/Array - 密钥的字节数组(16字节)iv: Uint8Array/Array - 初始向量的字节数组(16字节) | Uint8Array/Array - 解密后的字节数组 |
2.5.2、使用示例
// ECB模式示例
const key = gmcrypto.CommonUtils.utf8StrToHex('aostarit_2020-01'); // 16字节密钥
const plainText = 'Hello, 国密!';
// ECB加密解密
const cipherECB = gmcrypto.Sm4Utils.ECB.encryptFromText(plainText, key);
const decryptedECB = gmcrypto.Sm4Utils.ECB.decryptToText(cipherECB, key);
console.log(decryptedECB === plainText); // true
// CBC模式示例
const iv = gmcrypto.CommonUtils.utf8StrToHex('sgcc_sgitg_2020.'); // 16字节初始向量
// CBC加密解密
const cipherCBC = gmcrypto.Sm4Utils.CBC.encryptFromText(plainText, key, iv);
const decryptedCBC = gmcrypto.Sm4Utils.CBC.decryptToText(cipherCBC, key, iv);
console.log(decryptedCBC === plainText); // true2.6、注意事项
- 密钥安全:在实际应用中,请确保密钥的安全存储和传输
- 数据长度:SM2加密算法对于明文长度没有限制,但过长的明文可能会影响性能
- 密钥长度:SM4算法要求密钥和初始向量(IV)必须为16字节
- 编码格式:库内部使用UTF-8编码处理字符串
- 错误处理:在调用API时,应适当添加错误处理机制
2.7、许可证
ISC License
2.8、注意事项
- 本库主要用于前端加密和签名验证,服务端建议使用更安全的实现
- 密钥管理请遵循安全最佳实践
