Note
crypto
Node.js 内置的密码学模块,提供安全随机数、哈希、HMAC、加密解密、数字签名、密钥生成等能力
发布于 更新于
crypto
是 Node.js 内置的密码学模块,不是第三方库,它提供安全随机数、哈希、HMAC、加密解密、数字签名、密钥生成等能力。
引入
// node: 前缀表示这是 Node.js 核心模块,可以避免与 npm 中同名包混淆
import { createHmac, randomInt, timingSafeEqual } from "node:crypto";
// 也可以不使用node前缀。但是建议写前缀,因为可以一眼看出它不是第三方依赖,代码语义更加清晰
import * as crypto from "crypto";
randomInt()
生成指定范围内的密码学安全随机整数
参数与返回值
// 同步
randomInt(
min: number,
max: number,
): number;
// 省略min
randomInt(
max: number,
): number;
// 异步
randomInt(
min: number,
max: number,
callback: (error: Error | null, value: number) => void,
): void;
| 参数 | 含义 |
|---|---|
min |
随机数最小值,包含该值;省略时默认为 0 |
max |
随机数最大边界,不包含该值 |
callback |
可选回调函数;提供后使用异步方式生成 |
| 返回值 | 不传回调时返回随机整数 number |
示例
const value = randomInt(0, 10); // 可能得到0、1、2、3、4、5、6、7、8、9
// 生成随机6位数字。其中 1_000_000 与 1000000 完全相同,下划线只是方便阅读
const code = randomInt(0, 1_000_000).toString().padStart(6, "0");
createHmac()
使用“哈希算法 + 服务端密钥”创建一个 HMAC 计算对象。HMAC 可以简单理解为:
HMAC结果 = 密钥 + 原始数据 + 哈希算法共同计算出的摘要
例如
算法:SHA-256
密钥:my-secret
数据:test@example.com:REGISTER:123456
只要密钥或数据有任何变化,计算结果就会变化
HMAC 不是加密。不能从 HMAC 结果还原验证码,相同密钥和相同数据,会产生相同结果,没有服务端密钥,就无法正常计算对应结果
参数与返回值
createHmac(
algorithm: string,
key:
| string
| Buffer
| ArrayBuffer
| TypedArray
| DataView
| KeyObject,
options?: object,
): Hmac;
| 参数 | 含义 |
|---|---|
algorithm |
使用的哈希算法,例如 'sha256'、'sha512' |
key |
HMAC 密钥,也就是你代码中的 pepper |
options |
可选的流配置;普通验证码场景通常不需要 |
| 返回值 | 返回一个 Hmac 对象,还不是最终字符串 |
示例
// 1.创建计算器。此时只是创建了计算器,还没有告诉它要处理哪些数据
const hmac = createHmac("sha256", "my-secret");
hmac.update()
向 HMAC 对象中加入需要计算的数据
参数与返回值
hmac.update(
data: string | Buffer | TypedArray | DataView,
inputEncoding?: string,
): Hmac;
| 参数 | 含义 |
|---|---|
data |
要参与 HMAC 计算的数据 |
inputEncoding |
数据是字符串时所用的编码,默认是 'utf8' |
| 返回值 | 返回当前 Hmac 对象,所以可以继续链式调用 |
示例
// 2.向 HMAC 对象中加入需要计算的数据
hmac.update(data);
hmac.digest()
完成 HMAC 计算并取得最终结果
参数与返回值
hmac.digest(): Buffer;
hmac.digest(
encoding: string,
): string;
| 参数 | 含义 |
|---|---|
encoding |
可选输出编码,例如 'hex'、'base64' |
| 不传编码 | 返回二进制 Buffer |
传入 'hex' |
返回十六进制字符串 |
传入 'base64' |
返回 Base64 字符串 |
示例
// 3.完成 HMAC 计算并取得最终结果
hmac.digest("hex");
完整示例
完整使用“哈希算法 + 服务端密钥”创建一个 HMAC 计算对象
const result = createHmac("sha256", "my-secret")
.update("需要处理的数据")
.digest("hex");
timingSafeEqual()
安全地比较两段二进制数据是否完全相同。
参数与返回值
// a 和 b 的字节长度必须一致,否则会抛出异常
timingSafeEqual(
a: Buffer | ArrayBuffer | TypedArray | DataView,
b: Buffer | ArrayBuffer | TypedArray | DataView,
): boolean;
| 参数 | 含义 |
|---|---|
a |
第一段二进制数据 |
b |
第二段二进制数据 |
| 返回值 | 相同返回 true,不同返回 false |
示例
expected.length === actual.length && timingSafeEqual(expected, actual);