pem.mjs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import pem from 'pem'
  2. import { readFileSync } from 'fs'
  3. import crypto from 'crypto'
  4. import axios from 'axios'
  5. import { format, addSeconds } from 'date-fns'
  6. import qs from 'querystring'
  7. const privateKey = crypto.createPrivateKey({ key: readFileSync('certs/6888806043057.key') })
  8. const publicKey = crypto.createPublicKey({ key: readFileSync('certs/sand.crt') })
  9. function privSign(str) {
  10. const signer = crypto.createSign('SHA1')
  11. signer.update(str)
  12. signer.end()
  13. const signature = signer.sign(privateKey)
  14. return signature.toString('base64')
  15. }
  16. function verifySign(str, sign) {
  17. const verifier = crypto.createVerify('SHA1')
  18. verifier.update(str)
  19. verifier.end()
  20. return verifier.verify(publicKey, Buffer.from(sign.replace(/\s/g, '+'), 'base64'))
  21. }
  22. async function request(header, body, url) {
  23. const data = {
  24. head: header,
  25. body
  26. }
  27. const dataStr = JSON.stringify(data)
  28. console.log(JSON.stringify(data, null, 4))
  29. const sign = await privSign(dataStr)
  30. const postBody = {
  31. charset: 'UTF-8',
  32. data: dataStr,
  33. signType: '01',
  34. sign,
  35. extend: ''
  36. }
  37. console.log(qs.stringify(postBody))
  38. return await axios.post(url, qs.stringify(postBody), {
  39. headers: {
  40. 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
  41. },
  42. timeout: 30000,
  43. timeoutErrorMessage: '请求超时'
  44. })
  45. }
  46. const algorithm = 'aes-128-ecb'
  47. async function pay() {
  48. const data = {
  49. cityNo: '',
  50. productId: '00000004',
  51. bankType: '',
  52. payMode: '',
  53. accNo: '6222024301070380165',
  54. accName: '熊竹',
  55. bankName: '',
  56. remark: '消费',
  57. channelType: '',
  58. accAttr: '0',
  59. version: '01',
  60. timeOut: '20230506150701',
  61. extend: '',
  62. extendParams: '',
  63. tranTime: '20230506150401',
  64. provNo: '',
  65. phone: '',
  66. tranAmt: '000000000100',
  67. reqReserved: '',
  68. orderCode: new Date().getTime() + '',
  69. accType: '4',
  70. currencyCode: '156'
  71. }
  72. const dataStr = JSON.stringify(data)
  73. // 加密密钥,必须是 16、24 或 32 个字符长(分别对应 AES-128、AES-192 或 AES-256)
  74. const key = crypto.randomBytes(16)
  75. // 加密算法使用 AES-256-ECB
  76. // 将要加密的数据转换为一个 Buffer 对象
  77. const dataBuffer = Buffer.from(dataStr, 'utf8')
  78. // 创建一个加密器对象,使用 PKCS5Padding 进行补位
  79. const cipher = crypto.createCipheriv(algorithm, key, null)
  80. cipher.setAutoPadding(true)
  81. // 加密数据,并返回加密后的 Buffer 对象
  82. const encryptedBuffer = Buffer.concat([cipher.update(dataBuffer), cipher.final()])
  83. // 将加密后的 Buffer 对象转换为十六进制字符串
  84. const encrypted = encryptedBuffer.toString('base64')
  85. const sign = await privSign(dataStr)
  86. console.log(encrypted)
  87. const encryptKey = crypto
  88. .publicEncrypt(
  89. {
  90. key: publicKey,
  91. padding: crypto.constants.RSA_PKCS1_PADDING
  92. },
  93. key
  94. )
  95. .toString('base64')
  96. console.log(encryptKey)
  97. const body = {
  98. transCode: 'RTPM',
  99. accessType: '0',
  100. merId: '6888806043057',
  101. encryptKey: encryptKey,
  102. encryptData: encrypted,
  103. sign,
  104. extend: ''
  105. }
  106. const res = await axios.post('http://120.78.171.194:11223/agent-main/openapi/agentpay', qs.stringify(body))
  107. const retData = qs.parse(qs.unescape(res.data))
  108. console.log(retData)
  109. const decryptKey = crypto.privateDecrypt(
  110. {
  111. key: privateKey,
  112. padding: crypto.constants.RSA_PKCS1_PADDING
  113. },
  114. Buffer.from(retData.encryptKey.replace(/\s/g, '+'), 'base64')
  115. )
  116. console.log(decryptKey.toString())
  117. const decipher = crypto.createDecipheriv(algorithm, decryptKey, null)
  118. decipher.setAutoPadding(true)
  119. const decryptedBuffer = Buffer.concat([
  120. decipher.update(Buffer.from(retData.encryptData.replace(/\s/g, '+'), 'base64')),
  121. decipher.final()
  122. ])
  123. const decrypted = decryptedBuffer.toString('utf8')
  124. console.log(decrypted)
  125. const verify = verifySign(decrypted, retData.sign)
  126. console.log(verify)
  127. }
  128. await pay()