Node.js中使用HMAC进行hash加密

HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写。它的过程是把消息M和密钥s作为输入,使用hash算法生成一个定长的消息摘要。

HMAC目前在IPSec和其他网络协议(如SSL)中得以广泛应用。在nodejs中已经提供了crypto模块,不需要额外安装npm包。

我们以钉钉自定义机器人文档中要求的HmacSHA256为例说明如何使用,文档中关于加签的说明如下:

第一步,把timestamp+"\n"+密钥当做签名字符串,使用HmacSHA256算法计算签名,然后进行Base64 encode,最后再把签名参数再进行urlEncode,得到最终的签名(需要使用UTF-8字符集)。

const crypto = require('crypto');

const hmac = crypto.createHmac('sha256', 'your-secret-key')
            
hmac.update(Date.now() + '\n' + 'your-secret-key');

console.log(hmac.digest('base64')); // kXogg18q...

// 钉钉加签最后需要urlencode
// console.log(encodeURIComponent(hmac.digest('base64'))) 
// ceux%2BxGQccRY...

需要注意的是钉钉文档中注明,对最后的base64需要进行urlencode,所以我们使用encodeURIComponent对结果进行处理。

钉钉机器人SDK

针对nodejs平台,我发布了一款插件: 钉钉自定义机器人SDk, 支持文本 (text)、链接 (link)、markdown(markdown)、ActionCard、FeedCard消息类型。

安装

npm install dingtalk-robot-sdk --save-dev 

使用

// 初始化
const Robot = require("dingtalk-robot-sdk")
 
const robot = new Robot({
    accessToken: 'accessToken',
    secret: 'secret',
});
const Text = Robot.Text;
 
const text = new Text('我就是我,  @1825718XXXX 是不一样的烟火');
text.atPhone('1825718XXXX');
 
robot.send(text);

更多示例,点此查看

crypto.createHmac(algorithm, key[, options])

  • algorithm <string>
  • key <string> | <Buffer> | <TypedArray> | <DataView> | <KeyObject>
  • options <object> stream.transform

创建并返回一个Hmac对象。

algorithm是指定算法,key是用于生成HMAC哈希的密钥,options用来控制流的行为。

hmac.update(data[, inputEncoding])

  • data <string> | <Buffer> | <TypedArray> | <DataView>
  • inputEncoding <string> data 字符串的字符编码。

data为设置加签内容,inputEncoding表示字符编码,默认是utf8

hmac.digest([encoding])

  • encoding <string> 返回值的字符编码。
  • 返回: <Buffer> | <string>

计算hmac.update传入所有数据的HMAC摘要,如果指定encoding,就会返回字符串,否则会返回Buffer

如何生成某个文件的sha256 HMAC

const filename = process.argv[2];
const crypto = require('crypto');
const fs = require('fs');

const hmac = crypto.createHmac('sha256', '密钥');

const input = fs.createReadStream(filename);
input.on('readable', () => {
  // 哈希流只会生成一个元素。
  const data = input.read();
  if (data)
    hmac.update(data);
  else {
    console.log(`${hmac.digest('hex')} ${filename}`);
  }
});

0 条评论