crypto.getRandomValues
Web Crypto API 的 getRandomValues 方法,用于生成密码学安全的随机数。
#type / concept
#status / evergreen
#resource / javascript
#tech / dev / frontend
#platform / browser
#tech / security
[!info] related notes
- 所属 MOC: 安全 MOC
- 前置概念: 密码学
- 对比概念: [[Math.random]] (不安全)
- 使用场景: Fisher-Yates 洗牌算法, 密码生成, Token 生成
crypto.getRandomValues
一句话定义
crypto.getRandomValues() 是 Web Crypto API 提供的方法,使用密码学安全的伪随机数生成器 (CSPRNG) 填充 TypedArray,适用于生成密码、令牌等安全敏感场景。
核心机制
const array = new Uint32Array(1);
crypto.getRandomValues(array);
console.log(array[0]); // 0 到 4294967295 之间的安全随机整数
- 接受
Int8Array、Uint8Array、Uint16Array、Uint32Array等 TypedArray - 原地填充数组,返回同一个数组
- 底层使用操作系统级别的熵源(如
/dev/urandom)
环境兼容性
| 环境 | 支持情况 | 使用方式 |
|---|---|---|
| 浏览器 | ✅ 完全支持(包括 IE11) | window.crypto.getRandomValues() 或全局 crypto.getRandomValues() |
| Node.js 19+ | ✅ 全局可用 | 直接使用 crypto.getRandomValues() |
| Node.js 15-18 | ⚠️ 需要引入 | const { webcrypto } = require('crypto'); webcrypto.getRandomValues(...) |
| Node.js 14- | ❌ 不支持 | 使用 require('crypto').randomBytes |
最小例子:生成安全随机整数
function getSecureRandomInt(max) {
const array = new Uint32Array(1);
crypto.getRandomValues(array);
return array[0] % max; // 注意:取模有极微小偏差,日常使用可接受
}
// 生成 0-99 之间的随机数
const randomNum = getSecureRandomInt(100);
与 Math.random 的核心区别
| 特性 | Math.random() | crypto.getRandomValues() |
|---|---|---|
| 安全性 | ❌ 伪随机,可预测 | ✅ 密码学安全 |
| 随机源 | xorshift128+ 算法 | 操作系统熵池 |
| 适用场景 | 动画、游戏、非安全场景 | 密码、令牌、密钥生成 |
| 性能 | 更快 | 稍慢(但可忽略) |
| 可预测性 | 收集足够输出可推算 | 不可推算 |
常见使用场景
- 生成随机密码
- 生成 CSRF Token
- 生成 API Key
- Fisher-Yates 安全洗牌
- 生成 UUID/随机 ID
注意事项
- Modulo Bias:使用
%取模会引入极微小偏差,生成密码长度时可忽略;若需严格均匀,需使用 rejection sampling - 同步方法:
getRandomValues是同步的;若需异步随机数,使用crypto.randomUUID()或crypto.subtle.generateKey