const {KJUR, hextob64} = require('jsrsasign') const HashMap = { SHA256withRSA: 'SHA256withRSA', SHA1withRSA: 'SHA1withRSA' } const PEM_BEGIN = '-----BEGIN PRIVATE KEY-----\n' const PEM_END = '\n-----END PRIVATE KEY-----' /** * rsa签名参考:https://www.jianshu.com/p/145eab95322c */ exports.SignUtil = { /** * 创建签名 * @param params 请求参数 * @param privateKey 私钥,PKCS8 * @param signType 签名类型,RSA,RSA2 * @returns 返回签名内容 */ createSign(params, privateKey, signType) { const content = this.getSignContent(params) return this.sign(content, privateKey, signType) }, sign: function (content, privateKey, signType) { if (signType.toUpperCase() === 'RSA') { return this.rsaSign(content, privateKey, HashMap.SHA1withRSA) } else if (signType.toUpperCase() === 'RSA2') { return this.rsaSign(content, privateKey, HashMap.SHA256withRSA) } else { throw 'signType错误' } }, /** * rsa签名 * @param content 签名内容 * @param privateKey 私钥 * @param hash hash算法,SHA256withRSA,SHA1withRSA * @returns 返回签名字符串,base64 */ rsaSign: function (content, privateKey, hash) { privateKey = this._formatKey(privateKey) // 创建 Signature 对象 const signature = new KJUR.crypto.Signature({ alg: hash, //!这里指定 私钥 pem! prvkeypem: privateKey }) signature.updateString(content) const signData = signature.sign() // 将内容转成base64 return hextob64(signData) }, _formatKey: function (key) { if (!key.startsWith(PEM_BEGIN)) { key = PEM_BEGIN + key } if (!key.endsWith(PEM_END)) { key = key + PEM_END } return key }, /** * 获取签名内容 * @param params 请求参数 * @returns {string} */ getSignContent: function (params) { const paramNames = [] // 获取对象中的Key paramNames.push(...Object.keys(params || {}) // 过滤无效的KeyValue .filter(paramName => { // 参数名不为undefined且参数值不为undefined return !(typeof paramName === undefined || typeof params[paramName] === undefined) })) paramNames.sort() // 合成签名字符串 const paramNameValue = paramNames.map(paramName => { const val = params[paramName]; return `${paramName}=${val}` }) return paramNameValue.join('&') } }