Nodejs 微信加密訊息開發
阿新 • • 發佈:2019-01-30
最近在做微信接入,在採用明文訊息與微信伺服器進行通訊時,毫無壓力,改成密文後,微信提供了各種語言版本的demo,but 沒有nodejs。(複製一下,語文偏科,湊字數)。
做微信加密訊息主要下面幾個方面的內容:
-
加密前明文結構
-
16位元組的隨機字串
-
訊息長度的網路子節序
-
加密方式
-
加密演算法
-
填充塊計算方式
-
加密實現
1. 加密前明文結構: random(16B)+ msg_len(4B) + msg + $AppId;
說明:random(16B)為16位元組的隨機字串;msg_len為msg長度,佔4個位元組(網路位元組序),$AppId為公眾賬號的AppId
2. 16位元組隨機字串:沒啥說的直接拼接就好了
var randomPrefix = function(n) { var _str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; var buf = new Buffer(n); for (var i = 0; i < n; i++) { buf[i] = _str.charCodeAt(Math.floor(Math.random() * _str.length)); } return buf; };
3. 網路子節序:網路子節序根據訊息主體長度而生成
var htonl = function(n) {
var buf = new Buffer(4);
buf[0] = (n & 0xFF000000) >> 24;
buf[1] = (n & 0x00FF0000) >> 16;
buf[2] = (n & 0x0000FF00) >> 8;
buf[3] = (n & 0x000000FF) >> 0;
return buf;
};
4.加密方式:Base64_Encode(AES_Encrypt [random(16B)+ msg_len(4B) + msg + $AppId]);
5.加密演算法:AES採用CBC模式,祕鑰長度為32個位元組,資料採用PKCS#7填充;PKCS#7:K為祕鑰位元組數(採用32),buf為待加密的內容,N為其位元組數。Buf需要被填充為K的整數倍。在buf的尾部填充(K-N%K)個位元組,每個位元組的內容是(K- N%K);
6.填充塊計算方式: 訊息體長度 /32 ,
var padding = function(n) {
var len = n % 32;
if (len == 0) {
len = 32;
} else {
len = 32 - len;
}
var buf = new Buffer(len);
for (var i = 0; i < len; i++) {
buf[i] = len;
}
return buf;
};
7.加密實現:
1.加密採用crypto庫,
2.加密方式:aes-256-cbc,
3.key:
var encodingAESKey = new Buffer("YfWVs4vtcNf6FPFRqzJ2VT6LCmpppePaRyGJjt7Rlcr" + "=", 'base64');
4.IV:
encodingAESKey.slice(0, 16);
5. 建立加密物件方法:createCipheriv,
var cipher = crypto.createCipheriv('aes-256-cbc', encodingAESKey, encodingAESKey.slice(0, 16));
6. 取消自動填充
cipher.setAutoPadding(false);
7.加密並返回結果
cipher.update(Buffer.concat([preBuf, netBuf, msgBuf, corpBuf, paddingBuf]), "binary", 'base64') + cipher.final('base64'); // 解密資料
8.整體加密程式碼
var encrypt = function(msg) {
var msgBuf = new Buffer(msg, "utf-8"),
msgBufLength = msgBuf.length,
preBuf = randomPrefix(16),
netBuf = htonl(msgBufLength),
corpBuf = new Buffer(corpId, "utf-8"),
corpBufLength = corpBuf.length,
paddingBuf = padding(20 + msgBufLength + corpBufLength);
var cipher = crypto.createCipheriv('aes-256-cbc', encodingAESKey, encodingAESKey.slice(0, 16));
cipher.setAutoPadding(false); // 取消自動填充
return cipher.update(Buffer.concat([preBuf, netBuf, msgBuf, corpBuf, paddingBuf]), "binary", 'base64') + cipher.final('base64'); // 解密資料
};
歡迎加入node.js交流群:572416249原文:http://my.oschina.net/lvyuely/blog/598421