文章

Node.js三方module

Node.js三方module

nodemon

什么是 nodemon?

修改了代码后,不需要每次 node xxx.js 执行,nodemon 会自动帮我们重启项目,方便了开发和调试

安装 nodemon

1
2
3
npm install -g nodemon # 全局安装
# 或
npm i nodemon --D # dev_dep安装

使用 nodemon

node xxx.js 替换成 nodemon xxx.js

crypto module

crypto 模块的目的是为了提供通用的加密和哈希算法。用纯 JavaScript 代码实现这些功能不是不可能,但速度会非常慢。Nodejs 用 C/C++ 实现这些算法后,通过 cypto 这个模块暴露为 JavaScript 接口,这样用起来方便,运行速度也快。

MD5 和 SHA1

1
2
3
4
5
6
7
8
9
const crypto = require('crypto');

const hash = crypto.createHash('md5');

// 可任意多次调用update():
hash.update('Hello, world!');
hash.update('Hello, nodejs!');

console.log(hash.digest('hex')); // 7e1977739c748beac0c0fd14fd26a544
  • update() 方法默认字符串编码为 UTF-8,也可以传入 Buffer
  • 如果要计算 SHA1,只需要把 'md5' 改成 'sha1'
  • 还可以使用更安全的 sha256sha512

Hmac

Hmac 算法也是一种哈希算法,它可以利用 MD5 或 SHA1 等哈希算法。不同的是,Hmac 还需要一个密钥:

1
2
3
4
5
6
7
8
const crypto = require('crypto');

const hmac = crypto.createHmac('sha256', 'secret-key');

hmac.update('Hello, world!');
hmac.update('Hello, nodejs!');

console.log(hmac.digest('hex')); // 80f7e22570...

只要密钥发生了变化,那么同样的输入数据也会得到不同的签名,因此,可以把 Hmac 理解为用随机数 “ 增强 “ 的哈希算法。

AES

AES 是一种常用的对称加密算法,加解密都用同一个密钥。crypto 模块提供了 AES 支持,但是需要自己封装好函数,便于使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const crypto = require('crypto');

function aesEncrypt(data, key) {
    const cipher = crypto.createCipher('aes192', key);
    var crypted = cipher.update(data, 'utf8', 'hex');
    crypted += cipher.final('hex');
    return crypted;
}

function aesDecrypt(encrypted, key) {
    const decipher = crypto.createDecipher('aes192', key);
    var decrypted = decipher.update(encrypted, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
}

var data = 'Hello, this is a secret message!';
var key = 'Password!';
var encrypted = aesEncrypt(data, key);
var decrypted = aesDecrypt(encrypted, key);

console.log('Plain text: ' + data);
console.log('Encrypted text: ' + encrypted);
console.log('Decrypted text: ' + decrypted);

结果:

Plain text: Hello, this is a secret message! Encrypted text: 8a944d97bdabc157a5b7a40cb180e7… Decrypted text: Hello, this is a secret message!

注意到 AES 有很多不同的算法,如 aes192,aes-128-ecb,aes-256-cbc 等,AES 除了密钥外还可以指定 IV(Initial Vector),不同的系统只要 IV 不同,用相同的密钥加密相同的数据得到的加密结果也是不同的。加密结果通常有两种表示方法:hex 和 base64,这些功能 Nodejs 全部都支持,但是在应用中要注意,如果加解密双方一方用 Nodejs,另一方用 Java、PHP 等其它语言,需要仔细测试。如果无法正确解密,要确认双方是否遵循同样的 AES 算法,字符串密钥和 IV 是否相同,加密后的数据是否统一为 hex 或 base64 格式。

Diffie-Hellman

DH 算法是一种密钥交换协议,它可以让双方在不泄漏密钥的情况下协商出一个密钥来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Explain
const crypto = require('crypto');

// xiaoming's keys:
var ming = crypto.createDiffieHellman(512);
var ming_keys = ming.generateKeys();

var prime = ming.getPrime();
var generator = ming.getGenerator();

console.log('Prime: ' + prime.toString('hex'));
console.log('Generator: ' + generator.toString('hex'));

// xiaohong's keys:
var hong = crypto.createDiffieHellman(prime, generator);
var hong_keys = hong.generateKeys();

// exchange and generate secret:
var ming_secret = ming.computeSecret(hong_keys);
var hong_secret = hong.computeSecret(ming_keys);

// print secret:
console.log('Secret of Xiao Ming: ' + ming_secret.toString('hex'));
console.log('Secret of Xiao Hong: ' + hong_secret.toString('hex'));

RSA

RSA 算法是一种非对称加密算法,即由一个私钥和一个公钥构成的密钥对,通过私钥加密,公钥解密,或者通过公钥加密,私钥解密。其中,公钥可以公开,私钥必须保密。
RSA 算法是 1977 年由 Ron Rivest、Adi Shamir 和 Leonard Adleman 共同提出的,所以以他们三人的姓氏的头字母命名。
首先,我们用私钥加密,公钥解密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const
    fs = require('fs'),
    crypto = require('crypto');

// 从文件加载key:
function loadKey(file) {
    // key实际上就是PEM编码的字符串:
    return fs.readFileSync(file, 'utf8');
}

let
    prvKey = loadKey('./rsa-prv.pem'),
    pubKey = loadKey('./rsa-pub.pem'),
    message = 'Hello, world!';

// 使用私钥加密:
let enc_by_prv = crypto.privateEncrypt(prvKey, Buffer.from(message, 'utf8'));
console.log('encrypted by private key: ' + enc_by_prv.toString('hex'));


let dec_by_pub = crypto.publicDecrypt(pubKey, enc_by_prv);
console.log('decrypted by public key: ' + dec_by_pub.toString('utf8'));

执行后,可以得到解密后的消息,与原始消息相同。
接下来我们使用公钥加密,私钥解密:

1
2
3
4
5
6
7
// 使用公钥加密:
let enc_by_pub = crypto.publicEncrypt(pubKey, Buffer.from(message, 'utf8'));
console.log('encrypted by public key: ' + enc_by_pub.toString('hex'));

// 使用私钥解密:
let dec_by_prv = crypto.privateDecrypt(prvKey, enc_by_pub);
console.log('decrypted by private key: ' + dec_by_prv.toString('utf8'));

Nano ID 轻量级的唯一 id 生成库

https://github.com/ai/nanoid

chalk 终端样式美化

https://github.com/chalk/chalk

1
npm install chalk

使用

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
import chalk from 'chalk';

const log = console.log;

// Combine styled and normal strings
log(chalk.blue('Hello') + ' World' + chalk.red('!'));

// Compose multiple styles using the chainable API
log(chalk.blue.bgRed.bold('Hello world!'));

// Pass in multiple arguments
log(chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz'));

// Nest styles
log(chalk.red('Hello', chalk.underline.bgBlue('world') + '!'));

// Nest styles of the same type even (color, underline, background)
log(chalk.green(
	'I am a green line ' +
	chalk.blue.underline.bold('with a blue substring') +
	' that becomes green again!'
));

// ES2015 template literal
log(`
CPU: ${chalk.red('90%')}
RAM: ${chalk.green('40%')}
DISK: ${chalk.yellow('70%')}
`);

// Use RGB colors in terminal emulators that support it.
log(chalk.rgb(123, 45, 67).underline('Underlined reddish color'));
log(chalk.hex('#DEADED').bold('Bold gray!'));

报错

chalk 在 Node.js 中报错

uzfah

chalk5.x 是 ESM,需要用 chalk4.x

npm uninstall chalk npm install chalk@4.1.2

https://stackoverflow.com/a/77821551/5777306

JXcore 多线程打包

JXcore 是一个支持多线程的 Node.js 发行版本,基本不需要对你现有的代码做任何改动就可以直接线程安全地以多线程运行。

本文由作者按照 CC BY 4.0 进行授权