最近哥们问起SM2签名,发来一张图
一开始看不懂…
后来找到了js的库
npm install -save sm-crypto
这里直接说理解吧
sm2的加签, 会调用let sigValueHex = sm2.doSignature(msg,privateKey)
sm2的解签, 会调用
sm2.doSignature(msg,sigValueHex,publicKey)
复杂一点的加签 解签, 就是带sm3() 杂凑的模式
// 纯签名 + 生成椭圆曲线点 + sm3杂凑 let sigValueHex4 = sm2.doSignature(msg, privateKey, { hash: true, }) // 签名 let verifyResult4 = sm2.doVerifySignature(msg, sigValueHex4, publicKey, { hash: true, }) // 验签结果
带杂凑模式的要开启hash,同时传入的msg 可以通过 sm3(string)进行处理
加签操作
因此
针对上图的 SM2加解签步骤就好理解了
a. 通过特定的字符串组合, 计算出ZAlet ZA = sm3("某一串符合要求的字符串...")
b. 将ZA与MSG报文数据拼接, 再次进行 杂凑计算, 获取到 报文MSG的hash值 h
let h = sm3(ZA+MSG)
c. 执行 doSignature进行签名
//c. 计算 SingValue, 即执行加签 (hash模式启动 sm3杂凑) // 大S 存在 r/s两个子对象 let S = sm2.doSignature(h, s_privateKey, { hash: true, });
S 就是加签数据了, 其实是一串数值 , 可以通过取前后64 获取, 获取出来的就是上图中说的 小r和小s
r: new BigInteger(S.substring(0, 64), 16), s: new BigInteger(S.substring(64), 16),
解签操作
// 转字符串 S = S + "" let verify = sm2.doVerifySignature(msg_hash, S, publicKey,{ hash: true, }) //判断 verify true/false即可
完整代码
const {
BigInteger} = require('jsbn')
const sm2 = require('sm-crypto').sm2
const sm3 = require('sm-crypto').sm3
let keypair = sm2.generateKeyPairHex()
let publicKey = keypair.publicKey // 公钥
let s_privateKey = keypair.privateKey // 私钥
const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3,默认为1
const text = "王老师带我洗小头~"
var encryptData;
// 加密
function sm2_enc()