日期: 2021/10/25 天气:晴

    • test.js ```javascript /*
      • @Description:
      • @Author: 惜神
      • @Date: 2021-10-11 09:56:47 */ const axios = require(‘axios’); const uuid = require(‘uuid’); const moment = require(‘moment’); const qs = require(‘qs’); const { rsaSign, formatParams, bizSort, rsaVerify } = require(‘./util’); const host = ‘https://api.com.cn‘; const appid = ‘’;

    const mchPrivateKey = /YpX0SyHWzaC0hb5X7Vq+Wn3Oa83qti1k8me/ea2vWkpwGjW8zBaf9t8SMWDoEYzRmBD3VBiXdXdj7dbJhjciMW/8K7gbmi11Z+dwmCN6HVubEOO9xAL/ha0+EX60bI5xc+ORNJWuY4uqOhsyWlu5/ZHfoK5m2wLasaY8Z0axyZ6+ctMAg5WfMVEoJWYeLyD/WqgNj2hfKIlSuKElBKWTwGsVXeemjpThN/RGybRAbfBFXxt/xZExmejjAoO+8oN/+LAgMBAAECggEAN11sjPTAMwjZbl6ihLZNVfdsJ2FNL6r5oMjiQNO07o9GGY77upUQS58EJHYiiCY3RhDadNcbJCkMEkfx03b9DLfeLpVfqURPpbyeWAfxu4TTsX4ebZkB5eDWjWWIcWn38EJLuzw9ev/McsmPVzgWVs/v21lpuA3qNeQwIiC5zTYSVHZ/KMvAb62S9HlmFCjqhDjY1ChV5bbFXml0dxJ6AqJ1pbP9nwTgjOOyto6Po4fwCnjx/lh1lFnTJhPjnj9yMwyYaz4gfs92gT+DQVBFLp8RAOI2JxngcYog0qKokyabTKJwElBbYDraupBTEk8dluee2LikglBrMLMkVFXWIQKBgQD6bBOHcqJlEIYIhr6C/u2WfRYKAzy89dDgdmoDa/pyX9KsZFjLE/EnL/yckdjIqIDSYOX2wJkIP4x4WzHc/yCZiF7PFRqqpjDl58XDTQscUMAfNZmnBKL/+WIRR8NPuN+oSIDDTioBd5IUdiw6x4/dkekLeHzZIAFwBVmIDZjl8QKBgQCW9hoBejkJBgY7EQlM37SU3yY/dUsP0pxDDyTG37OcWFN/0zTPlii6jZH9kUX5KiNHypTdbCSVN/hpKDntyNWHpoSGkLYkp9oF3N8nIInhn85gzGxSFh8JyHxLVoZYQ/NYzj/yDR4yjSiuayNNqdjt4IprTg1Qv4L+SHjO3BYROwKBgQCIfS+Hu6tXelITg52CuH+2bib8/ha0xyY5sVDG3Kt8e03QOEFNLmlZ+oWssLF/bJgKElZEz2SZYkmlr87VrRiPlgxWwiHusPYl2NWpROyxWjHc0NIWfih5a+tPj9WcNh9xEVNdH9U1R36POHmS8AIxub1TSzCBBzjBXakWxpJ3gQKBgAOPpqlmQrYtyDPYgQmpNU9VvEc+8xhadYk3cDyoxknn44BecR58glV0RX9fz/DCx7ZH1x8qD+rdOSTx5/vuAuuCSBoMi99tfj0pKrJ3mAkUhf/OkreVAgJvEk+MqPqoD7OGmgeRu6ahodYLfPe2DAIAjANgAfxnqCVrfD4U/whFAoGBAKHmHsGrtQx90KYkTa3EkNwu8FbtvKOe799i/dStbl66J9Y43XTLhL4LtcJ/yXXNCs6IGpF3FOyOR2fktVe+d3vDkrPTuhiIRVxFUe/LpfTI1pauWUfNrV60c5gplRjR1gVWX0pX7XpW4c3S5c6dDtr8R1rg0f9MM/7XzC4SJ416

    const mchPubKey = +16bWZ5BMNgvEeuEQwfQYkRVwI9HFOGkwNTMn5hiJXHnlXYCX+zp5r6R52MY0O7BsTCLT7aHaxsANsvI9ABGx3OaTVlPB59M6GPbJh0uXvio0m1r/lTW3Z60RU6Q3oid/rNhP3CiNgg0W6O3AGqwIDAQAB

    class GSSDK { constructor(props) { this.mchPrivateKey = props && props.mchPrivateKey ? props.mchPrivateKey : mchPrivateKey; this.host = props && props.host ? props.host : host; }

    async getSign (url, params) { let formatBiz = bizSort(params.biz_content); params.biz_content = JSON.stringify(formatBiz); let sortString = formatParams(params, ‘&’); console.log(‘====sortString=====’, sortString) sortString = ${url}?${sortString}; const sign = rsaSign(sortString, this.mchPrivateKey, ‘SHA256withRSA’); return sign; }

    async verify(url, parmas, sign) { let formatBiz = bizSort(parmas.biz_content); parmas.biz_content = JSON.stringify(formatBiz); let sortString = formatParams(parmas, ‘&’); console.log(‘====sortString=====’, sortString) sortString = ${url}?${sortString}; console.log(‘====urlsortString=====’, sortString); const a = rsaVerify(sortString,mchPubKey,’SHA256withRSA’,sign) console.log(‘====aurlsortString=====’, a); }

    async commomParmas(bizContent) { const commonArgs = { app_id: appid, msg_id: uuid.v4(), format: ‘json’, charset: ‘UTF-8’, sign_type: ‘RSA2’, timestamp: moment().format(“YYYY-MM-DD hh:mm:ss”) } const fomartBizContent = { biz_content: bizContent } const args = Object.assign(commonArgs, fomartBizContent); return args; }

    async request ({ url, params }) { const args = await this.commomParmas(params); const sign = await this.getSign(url, args); console.log(‘====sign=====’, sign) const formatParams = Object.assign(args, { sign: sign }) console.log(‘====params====’, formatParams) return axios.post(${host}${url}, qs.stringify(formatParams), { headers: { ‘Content-Type’: ‘application/x-www-form-urlencoded; charset=UTF-8’ } }).then(res => { return Promise.resolve(res.data); }, err => { return Promise.reject(err); }) } }

    module.exports = GSSDK;

    1. - util.js
    2. ```javascript
    3. /*
    4. * @Description:
    5. * @Author: 惜神
    6. * @Date: 2021-10-11 09:57:37
    7. */
    8. const { KJUR, hextob64, b64tohex } = require('jsrsasign')
    9. module.exports = {
    10. formatKey: (key) => {
    11. const PEM_BEGIN = '-----BEGIN PRIVATE KEY-----\n'
    12. const PEM_END = '\n-----END PRIVATE KEY-----'
    13. if (!key.startsWith(PEM_BEGIN)) {
    14. key = PEM_BEGIN + key
    15. }
    16. if (!key.endsWith(PEM_END)) {
    17. key = key + PEM_END
    18. }
    19. return key
    20. },
    21. formatPubKey: (key) => {
    22. const PEM_BEGIN = '-----BEGIN PUBLIC KEY-----\n'
    23. const PEM_END = '\n-----END PUBLIC KEY-----'
    24. if (!key.startsWith(PEM_BEGIN)) {
    25. key = PEM_BEGIN + key
    26. }
    27. if (!key.endsWith(PEM_END)) {
    28. key = key + PEM_END
    29. }
    30. return key
    31. },
    32. rsaSign: (content, privateKey, hash) => {
    33. privateKey = module.exports.formatKey(privateKey)
    34. // 创建 Signature 对象
    35. const signature = new KJUR.crypto.Signature({
    36. alg: hash,
    37. //!这里指定 私钥 pem!
    38. prvkeypem: privateKey
    39. })
    40. signature.updateString(content)
    41. const signData = signature.sign()
    42. // 将内容转成base64
    43. return hextob64(signData)
    44. },
    45. rsaVerify: (content, pubKey, hash, sign) => {
    46. console.log('======content=========', content, '======pubKey====', pubKey, '====hash======', hash, '=======sign=======', sign)
    47. pubKey = module.exports.formatPubKey(pubKey)
    48. console.log('-------', pubKey)
    49. let signatureVf = new KJUR.crypto.Signature({ alg: 'SHA1withRSA', prvkeypem: pubKey });
    50. signatureVf.updateString(content);
    51. // !接受的参数是16进制字符串!
    52. let b = signatureVf.verify(b64tohex(sign));
    53. console.log("jsrsasign verify: " + b);
    54. return b
    55. },
    56. bizSort: (args) => {
    57. let keys = Object.keys(args);
    58. keys = keys.sort();
    59. let newArgs = {};
    60. keys.forEach(function (key) {
    61. newArgs[key] = args[key] //参数名区分大小写;
    62. })
    63. return newArgs;
    64. },
    65. formatParams: (args, join) => {
    66. let keys = Object.keys(args)
    67. keys = keys.sort()
    68. let newArgs = {}
    69. keys.forEach(function (key) {
    70. if (args[key] != "" && args[key] != 'undefined') { //如果参数的值为空不参与签名;
    71. newArgs[key] = args[key] //参数名区分大小写;
    72. }
    73. })
    74. let string = ''
    75. for (let k in newArgs) {
    76. string += join + k + '=' + newArgs[k]
    77. }
    78. string = string.substr(1)
    79. return string
    80. }
    81. }