首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >使用JavaScript生成安全的随机密码 - 技术解析与实践

使用JavaScript生成安全的随机密码 - 技术解析与实践

原创
作者头像
qife122
发布2025-08-02 23:25:13
发布2025-08-02 23:25:13
3150
举报

使用JavaScript生成安全的随机密码

最近我需要用JavaScript代码生成随机密码,但惊讶地发现很难找到正确的实现方法。Google、StackOverflow甚至ChatGPT提供的大多数方案都存在各种缺陷。

常见错误方案分析

错误示例1:使用不安全的Math.random()

代码语言:javascript
复制
/* 弱随机数生成器示例,禁止使用 */
var chars = "0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*()ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var passwordLength = 12;
var password = "";
for (var i = 0; i <= passwordLength; i++) {
  var randomNumber = Math.floor(Math.random() * chars.length);
  password += chars.substring(randomNumber, randomNumber +1);
}

MDN文档明确指出:Math.random()不提供加密安全的随机数,任何安全相关场景都应使用Web Crypto API的window.crypto.getRandomValues()方法。

错误示例2:浮点数舍入偏差

代码语言:javascript
复制
/* 存在浮点舍入偏差的示例,禁止使用 */
function generatePassword(length = 16) {
    let generatedPassword = "";
    const validChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,.-{}+!\"#$%/()=?";
    
    for (let i = 0; i < length; i++) {
        let randomNumber = crypto.getRandomValues(new Uint32Array(1))[0];
        randomNumber = randomNumber / 0x100000000;
        randomNumber = Math.floor(randomNumber * validChars.length);
        generatedPassword += validChars[randomNumber];
    }
    return generatedPassword;
}

此方案虽然使用了加密安全的随机数,但通过浮点数转换会引入不均匀分布问题。

错误示例3:模偏差问题

代码语言:javascript
复制
/* 存在模偏差的示例,禁止使用 */
var generatePassword = (
  length = 20,
  characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$'
) =>
  Array.from(crypto.getRandomValues(new Uint32Array(length)))
    .map((x) => characters[x % characters.length])
    .join('')

当随机数范围不是字符集大小的整数倍时,会导致某些字符出现概率更高。

正确实现方案

拒绝采样法

代码语言:javascript
复制
function simplesecpw() {
  const pwlen = 15;
  const pwchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  const limit = 256 - (256 % pwchars.length);

  let passwd = "";
  let randval;
  for (let i = 0; i < pwlen; i++) {
    do {
      randval = window.crypto.getRandomValues(new Uint8Array(1))[0];
    } while (randval >= limit);
    passwd += pwchars[randval % pwchars.length];
  }
  return passwd;
}

该方案具有三个关键特性:

  1. 使用加密安全的crypto.getRandomValues()
  2. 完全避免浮点数运算
  3. 通过拒绝采样消除模偏差

在线演示可在https://password.hboeck.de/体验,代码已开源发布在GitHub。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用JavaScript生成安全的随机密码
    • 常见错误方案分析
      • 错误示例1:使用不安全的Math.random()
      • 错误示例2:浮点数舍入偏差
      • 错误示例3:模偏差问题
    • 正确实现方案
      • 拒绝采样法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档