前言
近期同事咨询我和其他人验签时碰到的问题是,SHA256withECDSA签名不一样,我想到了以前使用的前端的算法库:jsrsasign,jsrsasign底层是使用的crpyto-js,有兴趣的可以自行去查看他们的源码,jsrsasign的文档很全面,很容易上手,即使不了解算法相关的知识也可以通过文档实现想要的功能,特别注意的一点是各种参数的格式很重要。
jsrsasign的github地址:https://github.com/kjur/jsrsasign,文档地址:https://kjur.github.io/jsrsasign/api/symbols/global__.html
crpyto-js的github地址:https://github.com/brix/crypto-js
基础运行环境
能编译es6的工具或环境都可以,比如webpage,umi
源码
import { KJUR, hextob64} from 'jsrsasign';
// eslint-disable-next-line import/prefer-default-export
export function SHA256withECDSA() {
// 公钥
let pk="-----BEGIN CERTIFICATE-----\n" +
"暂无=\n" +
"-----END CERTIFICATE-----";
// 私钥
let priK = `-----BEGIN PRIVATE KEY-----
MIGNAgEAMBAGByqGSM49AgEGBSuBBAAKBHYwdAIBAQQg0X+4+XL4R6yjWyXjLCeMx6BSqLC+tQ9o7Q0O6IMc05+gBwYFK4EEAAqhRANCAARawilZcih7sKoREMJkkkPo71vtcw9GX8FXcwXxUDnEjETfrLRID6AiqH7RDyPdKGx9nA5p+vbUyRFBWNmgWGX6
-----END PRIVATE KEY-----
`;
// 原文
var src = '{ "a": "LANHAISHENGTAI", "b": 1, "c": "d", "e": "system", "values": [{ "dateTime": 1577808000000, "dataValue": 12.3 }] }';
var sig = new KJUR.crypto.Signature({'alg':'SHA256withECDSA'});
sig.init(priK);
sig.updateString(src);
var sigValueHex = sig.sign();// 签名hex ecdsa每次的签名是不同的
console.log(hextob64(sigValueHex)); // base64格式的签名
// 以下是官方示例
// // ECDSA signing 签名
// var sig = new KJUR.crypto.Signature({'alg':'SHA1withECDSA'});
// sig.init(prvKeyPEM);
// sig.updateString('aaa');
// var sigValueHex = sig.sign();
// // ECDSA verifying 验签
// var sig2 = new KJUR.crypto.Signature({'alg':'SHA1withECDSA'});
// sig.init(certPEM);
// sig.updateString('aaa');
// var isValid = sig.verify(sigValueHex);
}
特殊说明
私钥需要时pem格式,形如:
-----BEGIN PRIVATE KEY----- 开始标记
私钥内容,需要是KJUR.crypto.ECDSA()生成的签名格式,不让这个地方会提示一个错误说找不到alg:ecdsa这类的提示,如果查看jsrsasign源码时可以看到这一行代码的
-----END PRIVATE KEY----- 结束标记