Nodejs 微信加密消息开发


最近在做微信接入,在采用明文消息与微信服务器进行通信时,毫无压力,改成密文后,微信提供了各种语言版本的demo,but 没有nodejs。(复制一下,语文偏科,凑字数)。

做微信加密消息主要下面几个方面的内容:

  1. 加密前明文结构

  2. 16字节的随机字符串

  3. 消息长度的网络子节序

  4. 加密方式

  5. 加密算法

  6. 填充块计算方式

  7. 加密实现

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

没有更多推荐了,返回首页