-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
125 lines (98 loc) · 3.4 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
const aesjs = require('aes-js');
const assert = require('assert');
const crypto = require('crypto');
const bufferpack = require('bufferpack');
// aes document: https://www.npmjs.com/package/aes-js
function sign(token, timestamp, nonce, msg_encrypt) {
let array = [token, timestamp, nonce, msg_encrypt];
array = array.sort();
let str = array.join('');
let sha1 = crypto.createHash('sha1');
sha1.update(str, 'utf8');
let signature = sha1.digest('hex');
return signature;
}
function customPadding(buffer) {
let BLOCK_SIZE = 32;
let amountToPad = BLOCK_SIZE - (buffer.length % BLOCK_SIZE);
if (amountToPad == 0) {
amountToPad = BLOCK_SIZE;
}
let padChr = String.fromCharCode(amountToPad);
let tmp = '';
for (let i = 0; i < amountToPad; i++) {
tmp += padChr;
}
let padBuffer = new Buffer(tmp);
return padBuffer;
}
function pack(number) {
let value = bufferpack.pack('I', [number]);
return value;
}
function unpack(buffer) {
// let buffer = new Buffer(chars, 'latin1');
let origin = bufferpack.unpack('I', buffer)
return origin[0];
}
class Aes {
constructor(_aesKey, corpId, token) {
let aesKey = _aesKey;
if (_aesKey.length === 43) {
aesKey = Buffer.from(_aesKey + "=", 'base64');
}
let iv = aesKey.slice(0, 16);
token = token || '123456';
this.corpId = corpId;
this.token = token;
this.aesKey = aesKey;
this.iv = iv;
}
decode(encrypt, timestamp, nonce, signature) {
// 验签
let sig = sign(this.token, timestamp, nonce, encrypt);
assert(sig === signature, 'signature匹配正确');
let decodedStr = this._decode(encrypt);
// 获得内容字符长度
let len = unpack(decodedStr.slice(16, 20));
// 根据长度获取内容
let decrypt = decodedStr.slice(20, 20 + len);
decrypt = decrypt.toString('utf8');
try {
let jsonParsed = JSON.parse(decrypt);
return jsonParsed
} catch (e) {
return decrypt;
}
}
encode(encodeStr = 'success', msg_timestamp = Date.now(), msg_nonce = 'KOHjp9ss') {
let concatStr = '1234567890123456' + pack(encodeStr.length).toString('latin1') + encodeStr + this.corpId;
let encrypt = this._encode(new Buffer(concatStr));
let msg_signature = sign(this.token, msg_timestamp, msg_nonce, encrypt);
let result = {
"msg_signature": msg_signature,
"timeStamp": msg_timestamp,
"nonce": msg_nonce,
"encrypt": encrypt
};
return result;
}
_encode(buffer) {
let padBuffer = customPadding(buffer);
buffer = Buffer.concat([buffer, padBuffer]);
let aesCbc = new aesjs.ModeOfOperation.cbc(this.aesKey, this.iv);
// decryptedBytes 非标准buffer
let encryptedBytes = aesCbc.encrypt(buffer);
let encryptedHex = new Buffer(encryptedBytes).toString('base64');
return encryptedHex;
}
_decode(b64string) {
let buffer = Buffer.from(b64string, 'base64');
let aesCbc = new aesjs.ModeOfOperation.cbc(this.aesKey, this.iv);
// decryptedBytes 非标准buffer
let decryptedBytes = aesCbc.decrypt(buffer);
let decryptedBuffer = new Buffer(decryptedBytes);
return decryptedBuffer;
}
}
module.exports = Aes;