const express = require('express');
const xmlparser = require('express-xml-bodyparser');
const WXMsgCrypto = require("./WXMsgCrypto");
const app = express();
let token = "KAEtDpmTvxxxxxxxxxxxxxx"
let encodingAESKey = "HXzrNueLGgv82xxxxxxxxxxx"
let appId = "wx014xxxxxxxxxxx"
let wxmc = new WXMsgCrypto(token, encodingAESKey, appId)
app.use(xmlparser())
app.post('/wx', async (req, res) => {
let body = req.body
let query = req.query
let encrypt = body.xml.encrypt[0]
let encryptJson = wxmc.decrypt(encrypt)
let xmlbody = await xmlParser.parseStringPromise(encryptJson.message);
console.log(body);
console.log(query);
console.log(xmlbody);
aaa = xmlbody.xml.ComponentVerifyTicket
console.log(aaa);
res.json("success")
})
app.all('*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Methods', '*');
res.header('Content-Type', 'application/json;charset=utf-8');
next();
});
app.listen(8090, '127.0.0.1', function (res, req) {
console.log("应用实例,访问地址为 http://127.0.0.1:8090")
})
const crypto = require("crypto");
class PKCS7 {
decode(text) {
let pad = text[text.length - 1];
if (pad < 1 || pad > 32) {
pad = 0;
}
return text.slice(0, text.length - pad);
}
encode(text) {
const blockSize = 32;
const textLength = text.length;
const amountToPad = blockSize - (textLength % blockSize);
const result = Buffer.alloc(amountToPad);
result.fill(amountToPad);
return Buffer.concat([text, result]);
}
}
class WXMsgCrypto {
constructor(token, encodingAESKey, appId) {
if (!token || !encodingAESKey || !appId) {
throw new Error("please check arguments");
}
this.token = token;
this.appId = appId;
let AESKey = Buffer.from(encodingAESKey + "=", "base64");
if (AESKey.length !== 32) {
throw new Error("encodingAESKey invalid");
}
this.key = AESKey;
this.iv = AESKey.slice(0, 16);
this.pkcs7 = new PKCS7();
}
getSignature(timestamp, nonce, encrypt) {
const sha = crypto.createHash("sha1");
const arr = [this.token, timestamp, nonce];
if (encrypt) {
arr.push(encrypt);
}
arr.sort();
sha.update(arr.join(""));
return sha.digest("hex");
}
decrypt(text) {
const decipher = crypto.createDecipheriv("aes-256-cbc", this.key, this.iv);
decipher.setAutoPadding(false);
let deciphered = Buffer.concat([
decipher.update(text, "base64"),
decipher.final()
]);
deciphered = this.pkcs7.decode(deciphered);
const content = deciphered.slice(16);
const length = content.slice(0, 4).readUInt32BE(0);
return {
message: content.slice(4, length + 4).toString(),
appId: content.slice(length + 4).toString()
};
}
encrypt(text) {
const randomString = crypto.pseudoRandomBytes(16);
const msg = Buffer.from(text);
const msgLength = Buffer.alloc(4);
msgLength.writeUInt32BE(msg.length, 0);
const id = Buffer.from(this.appId);
const bufMsg = Buffer.concat([randomString, msgLength, msg, id]);
const encoded = this.pkcs7.encode(bufMsg);
const cipher = crypto.createCipheriv("aes-256-cbc", this.key, this.iv);
cipher.setAutoPadding(false);
const cipheredMsg = Buffer.concat([cipher.update(encoded), cipher.final()]);
return cipheredMsg.toString("base64");
}
}
module.exports = WXMsgCrypto;