UNPKG

wx

Version:

W(ei)X(in) -- (minimalist) WeChat Middleware for Express.js

133 lines (114 loc) 4.08 kB
// Generated by CoffeeScript 1.10.0 (function() { var PKCS7, Prpcrypt, WXBizMsgCrypt, crypto, generated_signature, xml2js; crypto = require('crypto'); xml2js = require('xml2js'); PKCS7 = (function() { var block_size; block_size = 32; return { encode: function(data) { var amount_to_pad, buf; amount_to_pad = block_size - (data.length % block_size); if (amount_to_pad === 0) { amount_to_pad = block_size; } buf = new Buffer(amount_to_pad); buf.fill(String.fromCharCode(amount_to_pad)); return Buffer.concat([data, buf]); }, decode: function(data) { var pad; pad = data.readUInt8(data.length - 1); if (pad < 1 || pad > 32) { pad = 0; } return data.slice(0, data.length - pad); } }; })(); Prpcrypt = (function() { var get_random_str; function Prpcrypt(key) { this.key = new Buffer(key + '=', 'base64'); } get_random_str = function() { var i, j, str, str_pol; str = ''; str_pol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"; for (i = j = 0; j <= 15; i = ++j) { str += str_pol[parseInt(Math.random() * str_pol.length)]; } return str; }; Prpcrypt.prototype.encrypt = function(text, appid) { var buf, cipher, cipherChunks, iv, msg_len; msg_len = 16 + 4 + Buffer.byteLength(text) + appid.length; buf = new Buffer(msg_len); buf.write(get_random_str(), 0); buf.writeUInt32BE(Buffer.byteLength(text), 16); buf.write(text, 20); buf.write(appid, Buffer.byteLength(text) + 20); iv = this.key.slice(0, 16); buf = PKCS7.encode(buf); cipher = crypto.createCipheriv('aes-256-cbc', this.key, iv); cipher.setAutoPadding(false); cipherChunks = [cipher.update(buf, 'binary', 'base64'), cipher.final('base64')]; return cipherChunks.join(''); }; Prpcrypt.prototype.decrypt = function(text, appid) { var buf, decipher, iv, plainChunks; iv = this.key.slice(0, 16); decipher = crypto.createDecipheriv('aes-256-cbc', this.key, iv); decipher.setAutoPadding(false); plainChunks = [decipher.update(text, 'base64'), decipher.final()]; buf = Buffer.concat(plainChunks); buf = PKCS7.decode(buf); buf = buf.slice(20, buf.length - appid.length); return buf.toString('utf8'); }; return Prpcrypt; })(); generated_signature = function(token, timestamp, nonce, encrypt) { var sha1; sha1 = crypto.createHash('sha1'); sha1.update([token, timestamp, nonce, encrypt].sort().join('')); return sha1.digest('hex'); }; WXBizMsgCrypt = (function() { function WXBizMsgCrypt(token1, key1, appId) { this.token = token1; this.key = key1; this.appId = appId; if (this.key.length !== 43) { throw 'Key is not valid.'; } } WXBizMsgCrypt.prototype.encrypt = function(msg, timestamp, nonce) { var encrypt, pc, signature; pc = new Prpcrypt(this.key); encrypt = pc.encrypt(msg, this.appId); signature = generated_signature(this.token, timestamp, nonce, encrypt); return "<xml> <Encrypt><![CDATA[" + encrypt + "]]></Encrypt> <MsgSignature><![CDATA[" + signature + "]]></MsgSignature> <TimeStamp>" + timestamp + "</TimeStamp> <Nonce><![CDATA[" + nonce + "]]></Nonce> </xml>"; }; WXBizMsgCrypt.prototype.decrypt = function(msg, callback) { return xml2js.parseString(msg, (function(_this) { return function(err, result) { var pc, xml; if (err) { throw err; } xml = result.xml; if (xml.Encrypt) { pc = new Prpcrypt(_this.key); return xml2js.parseString(pc.decrypt(xml.Encrypt[0], _this.appId), callback); } else { return callback('Not encrypted.', null); } }; })(this)); }; return WXBizMsgCrypt; })(); module.exports = WXBizMsgCrypt; }).call(this);