这个生成器如何生成密码
点击按钮后,浏览器通过 crypto.getRandomValues() 从操作系统的安全随机源取值,再逐个字符地挑选。 你勾选的每种字符类型,都会先各放入一个字符,其余位置从所有已选类型合并后的字符池里抽取,最后把整体随机打乱。因此不会出现"选了四种类型,结果一个数字都没有"的情况。
把随机数变成字符时有两个常见陷阱,本工具都避开了。其一,把32位随机数直接对字符池大小取余,当池大小不是2的幂时,排在前面的字符会有极其微小的概率优势(取模偏差)。脚本丢弃落在偏差区间的随机值并重新抽取(拒绝采样),让每个字符的概率完全相同。 其二,如果挑字符与打乱顺序共用同一批随机数,两个步骤会互相关联,降低有效随机性。这里的Fisher-Yates洗牌在每次交换时都重新取一个随机数。
如何读懂熵值与破解耗时
熵值表示:假设攻击者知道生成方式,需要尝试多少次才能猜中,并用2的幂的指数来表示。字符池大小为N、长度为L,且每个字符独立均匀抽取时,可能的密码共有N^L种,熵值为 L × log2(N) 比特。每增加1比特,组合数翻一倍。 平均而言试到一半组合就能命中,所以平均耗时为 2^(比特数−1) ÷ 每秒尝试次数。本页的表格和工具界面都假设每秒100亿次,这是对"泄露的哈希文件被多块GPU离线破解"的一种简化。 实际速度会因服务端采用的哈希算法而相差数千倍以上(bcrypt、Argon2这类刻意变慢的算法让每次猜测的成本高得多)。请把耗时当作比较不同设置的尺子,而不是对寿命的预言。
字符组成与长度对应的熵值和平均破解耗时
下表在构建时计算。每个单元格上一行是熵值(比特),下一行是按每秒100亿次估算的平均耗时。基准是未排除易混淆字符的完整字符池(大写26、小写26、数字10、符号18),并假设每个字符独立、等概率抽取。
| 字符组成(池大小) | 6位 | 8位 | 10位 | 12位 | 16位 | 20位 |
|---|---|---|---|---|---|---|
| 仅数字 (10) | 20 比特 不到1秒 | 27 比特 不到1秒 | 33 比特 不到1秒 | 40 比特 50秒 | 53 比特 6天 | 66 比特 158年 |
| 仅小写字母 (26) | 28 比特 不到1秒 | 38 比特 10秒 | 47 比特 2小时 | 56 比特 55天 | 75 比特 7万年 | 94 比特 316亿年 |
| 小写字母+数字 (36) | 31 比特 不到1秒 | 41 比特 2分钟 | 52 比特 2天 | 62 比特 8年 | 83 比特 1,261万年 | 103 比特 远超宇宙年龄(约138亿年) |
| 大小写字母+数字 (62) | 36 比特 3秒 | 48 比特 3小时 | 60 比特 1年 | 71 比特 5,112年 | 95 比特 755亿年 | 119 比特 远超宇宙年龄(约138亿年) |
| 大小写字母+数字+18种符号 (80) | 38 比特 13秒 | 51 比特 23小时 | 63 比特 17年 | 76 比特 11万年 | 101 比特 远超宇宙年龄(约138亿年) | 126 比特 远超宇宙年龄(约138亿年) |
从表中可以看出:加长比增加类型有效得多。仅用小写字母的20位(94比特),字符池只有26,却高于用全部80种字符的10位(63比特)。多一位,组合数乘以池大小;而加入符号扩大字符池,只是在对数上加了一点。
验算过的计算示例
示例1:默认设置(16位,四种类型全选)
排除易混淆字符后,字符池为大写24 + 小写25 + 数字8 + 符号18 = 75个。 熵值为 16 × log2(75) ≈ 100 比特,按每秒100亿次估算平均耗时为远超宇宙年龄(约138亿年)。 (由于"每种所选类型至少出现一次"的规则,真实的密码总数比上面的算式略少一点,但在16位时差别可以忽略。)
示例2:12位小写字母+数字(排除易混淆字符)
字符池为25 + 8 = 33个,12 × log2(33) ≈ 61 比特,平均耗时3年。对有锁定机制的在线登录绰绰有余,但对哈希可能泄露、会遭离线攻击的重要账号,建议16位以上。
示例3:6位数字PIN
10种数字、6个位置,6 × log2(10) ≈ 20 比特,恰好100万种组合。离线只要不到1秒;但对输错5次就锁定的服务来说,仍然够用。同一个秘密,取决于攻击者能猜多快,安全程度可以相差很大。
设置建议
- 邮箱、金融、云存储等核心账号:16位以上,四种类型全选,存入密码管理器,并开启两步验证。
- 普通商城、论坛:12到16位,每个网站务必不同。一个站点泄露后,攻击者会拿同一个密码去其他站点试(撞库)。
- 不允许符号或只允许部分符号的网站:取消符号,再加长4到6位来弥补。
- 需要手动输入的密码(电视、游戏机、Wi-Fi):保持"排除易混淆字符"开启,可避免把大写I、小写l、数字1,或大写O和数字0看混。字符池变小的损失,多加一两位即可补回。
- 必须背下来的主密码:几个随机单词比一串随机符号更好记,可以试试密码短语生成器。
比起复杂度规则,更重要的是长度和随机性
"必须包含大写、数字、符号各一个"这类规则,在人工设置密码时往往催生出 Password1!、Summer2024! 这样一眼能看穿的变形。破解工具早已把这些模式(单词+数字+结尾符号、用符号替换字母等)放进字典,并优先尝试。 美国NIST的数字身份指南(SP 800-63B)倾向于:允许足够长的密码、与已泄露密码列表比对、避免强制组合规则和定期更换。具体的最小长度在不同修订版中有所变化,制定规则时请查阅最新文本。 随机生成的字符串没有这些人为习惯,这是它与自选密码的本质区别。
常见错误与误解
- "加了符号就安全":
P@ssw0rd!有三个符号,却是最先被尝试的典型。关键在于随机性。 - "生成的密码必须背下来":不需要。让密码管理器去记,脑子里只留一个主密码。
- "必须定期更换":真正有用的是怀疑泄露时立刻更换。强制定期更换往往导致人们只把末尾数字加一这类弱变化。
- 把耗时当成事实:这是带假设的模型。服务端的哈希方式、尝试次数限制以及文件是否泄露,都会改变实际情况。
- 把生成的密码明文存在聊天软件或记事本里:这是最常见的泄露途径。复制后立刻粘贴进密码管理器,再复制别的内容覆盖剪贴板。
本工具的局限与不适用的情形
- 工具只在浏览器内运行,但如果设备上装有恶意浏览器扩展或恶意软件,屏幕上的内容仍可能泄露。请不要在你怀疑已被入侵的电脑上使用。
- 如果网站不接受某些符号或限制长度(例如最长12位),请相应调整选项。这里使用的18种符号中,有些可能被个别网站拒绝。
- 熵值只对"随机生成且未被改动"的密码有意义。若你为了好记而修改了其中几位,这个计算就不再成立。
- 加密密钥、API令牌这类由系统直接使用的秘密值,请遵循对应系统推荐的生成方式(例如32字节随机数)。
生成之后该做什么
- 先把密码存进密码管理器,再粘贴到网站的修改密码页面。顺序反过来的话,可能还没保存就关了页面,导致无法登录账号。
- 开启两步验证,这样即使密码泄露,还有第二道屏障。
- 把其他用了同一个密码的网站也一并更换。
- 想评估已有密码的强度,可以用密码强度检测器,但最好输入结构相似的字符串,而不是真实密码。
相关工具:哈希生成器(了解保存的密码如何变成哈希)、UUID生成器(随机标识符)。
常见问题
生成的密码会被保存或发送到服务器吗?
不会。生成全部在浏览器内完成,关闭或刷新页面后即消失。脚本里没有发送它的代码,也不会写入浏览器存储。当然,复制之后它会留在你的剪贴板里。
多长的密码才算安全?
四种类型全选(默认排除易混淆字符)并随机生成时,12位约75比特,16位约100比特。一般服务建议至少12位,邮箱、金融等核心账号建议16位以上。可对照上面的表格比较不同长度。
为什么默认排除 I、O、l、0、1 这些字符?
在许多字体中,大写I、小写l和数字1几乎一模一样,O和0也容易混淆。默认排除是为了减少手动输入时的错误。取消勾选后,将从完整的80个字符中抽取;字符池略小,多加一两位即可补回。
和用Math.random()生成的密码有什么不同?
Math.random()面向统计上的均匀分布,并非为安全设计,许多实现中观察一些输出就能推断其内部状态并预测后续值。crypto.getRandomValues()使用操作系统的安全随机源,其设计目标就是让预测在现实中不可行。
密码足够长的话,在多个网站重复使用也可以吗?
不可以。长度只能抵御暴力破解;如果某个网站以明文或弱哈希泄露了它,攻击者会直接拿同一个值去别的网站试。无论多长,每个网站都应使用不同的密码。
本文为一般性信息,不能替代所在机构的安全政策或专业人士的建议。