crypto
模块现在是 node@10 中的一个内置模块了,其提供了加密功能,包括对 OpenSSL 的哈希、HMAC、加密、解密、签名、以及验证功能的一整套封装。
代码中引用如下:
const crypto = require('crypto');
还可以检测当前环境是否支持 crypto:
let crypto ;
try {
crypto = require('crypto');
} catch (err) {
console.error('不支持 crypto');
}
Hash
类是用于创建数据哈希值的工具类,其包含的算法有:
crypto.createHash(algorithm)
所支持的算法如下可以通过终端命令查看下。
可以在终端上查看支持的算法:
# 新版本 OpenSSL 的命令
$ openssl list -digest-algorithms
# 旧版本 OpenSSL 的命令
$ openssl list-message-digest-algorithms
其可如下使用:
流
的特性,既可读又可写;hash.update()
和 hash.digest()
方法产生计算后的哈希。单次与多次读写:
const crypto = require('crypto');
class MySHA256Cryptor {
constructor () {
this.result = '';
this.hasher = null;
this.init();
}
init () {
this.result = '';
this.hasher = crypto.createHash('sha256');
this.hasher.on('readable', () => {
// 哈希流只会生成一个元素。
const data = this.hasher.read();
if (data) {
this.result = data.toString('hex');
} else {
this.result = '';
}
});
}
updateStr (str) {
this.hasher.write(str);
return this;
}
getResult () {
this.hasher.end()
return this.result;
}
}
console.log(
(new MySHA256Cryptor()).updateStr('ILOVEYOU').getResult()
);
console.log(
(new MySHA256Cryptor())
.updateStr('I')
.updateStr('LOVE')
.getResult()
);
管道流读写:
const fs = require('fs');
const stream = require('stream');
const crypto = require('crypto');
const hasher = crypto.createHash('sha256');
const fsStream = fs.createReadStream('./demos/file.txt');
stream.pipe(hasher);
hasher.on('readable', () => {
// 一些处理操作
});
hash.update()
和 hash.digest()
计算哈希需求场景:例如需要将 timestamp
、token
、 userId
和 userName
的值拼凑成字符串,然后使用 SHA256 的方式加密生成一个「签名」字符串。
const crypto = require('crypto');
const str = `${timestamp},${token},${userId},${userName}`;
const sha256 = function (str) {
const hash = crypto.createHash('sha256');
hash.update(str);
// 返回16进制hash码
// 这里可以根据自己的需求
// 另外要注意,返回的是大写字母
return hash.digest('hex');
}
console.log(
sha256(str);
);
服务端流式读取文件内容并计算 MD5 值,这样可以减少内存消耗:
const fs = require('fs');
const crypto = require('crypto');
const fsSha1 = crypto.createHash('sha1');
const stream = fs.createReadStream(filepath);
const chunkArr = [];
stream.on('data', (chunk) => {
fsSha1.update(chunk);
chunkArr.push(chunk);
});
stream.on('end', () => {
const buffer = Buffer.concat(chunkArr);
// 整个文件内容的字节大小,可以作为 Content-length
console.log(buffer.byteLength);
const sha1 = fsSha1.digest('hex');
// 文件内容的校验码
console.log(sha1);
});
当然,其实直接使用方法 1 的「管道流式」读取即可了。
← 前言