node将对象按照ASCII码进行升序排列生成签名字符串,然后加载 pfx证书进行SHA256withRSA加密

 GitHub - Dexus/pem: Create private keys and certificates with node.js

安装 openSSL(v1.1.1) Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions

或者使用Chocolatey安装:choco install openssl(root权限)

import * as pem from 'pem';
import * as fs from 'fs';
import * as NodeRSA from 'node-rsa';

pem.config({
  pathOpenSSL: 'C:\\Program Files\\OpenSSL-Win64\\bin\\openssl'
})

async function createSign(obj) {
  const plaintext = getSignStr(obj);
  const privateKey = await readPem();
  return rsaSign(plaintext, privateKey, 'SHA256withRSA');
}

function getSignStr(obj) {
  const sortObj = sortASCII(obj,true);
  let singStr = ''
  for (const key in sortObj) {
    singStr += `${key}=${sortObj[key]}&`;
  }
  return singStr.slice(0, -1);
}

async function readPem() {
  const pfx = fs.readFileSync('C:/.../xx.pfx');
  return new Promise(async (resolve, reject) => {
    pem.readPkcs12(pfx, { p12Password: 'sumpay' }, (err, cert) => {
      console.log('err::: ', err);
      const RSAKey = cert.key;
      const key = new NodeRSA(RSAKey);
      const privateKey = key.exportKey("pkcs8");
      resolve(privateKey);
    });
  });
}

/**
 * 传入一个对象和布尔值,return根据ASCII码升序或者降序的对象
 * isSort: true代表升序,false代表降序
 * */
function sortASCII(obj, isSort) {
  let arr = []
  Object.keys(obj).forEach(item => arr.push(item))
  let sortArr = isSort ? arr.sort() : arr.sort().reverse()
  let sortObj = {}
  for (let i in sortArr) {
    sortObj[sortArr[i]] = obj[sortArr[i]]
  }
  return sortObj
}

/**
 * rsa签名
 * @param content 签名内容
 * @param privateKey 私钥,PKCS#1
 * @param hash hash算法,SHA256withRSA,SHA1withRSA
 * @returns 返回签名字符串,base64
 */
function rsaSign(content, privateKey, hash) {
  privateKey = _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)
}

function _formatKey(key) {
  if (!key.startsWith(PEM_BEGIN)) {
    key = PEM_BEGIN + key
  }
  if (!key.endsWith(PEM_END)) {
    key = key + PEM_END
  }
  return key
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值