密码生成器:取的是真随机数,强度数字也讲实话
用浏览器的密码学随机数配合拒绝采样生成密码,不让任何一个字符被悄悄偏爱;然后读出比特数、平均猜测次数,以及这些数字说不清的部分 —— 尤其是你自己输入的那种密码。全部运算都在这个标签页里完成,你输入的内容不会离开这台设备。
候选密码
| # | 密码 | 比特 |
|---|
测量一个你已经在用的密码
| 项目 | 值 |
|---|
随机数怎么取、强度多少
随机数到底是怎么取的
一个生成出来的密码要值钱,三件事都得对,而大多数玩具生成器至少搞错一件。
- 数字来自操作系统。
crypto.getRandomValues是浏览器通向同一个随机源的窗口,密码管理器用的也是它。Math.random是一个用时钟播种的 xorshift:拿到它输出的几个数就足够推出内部状态、猜出后面所有的数,于是"生成的"就变成"可猜的"。浏览器不肯给密码学随机数时,宁可拒绝生成,也不会退回到一个更安静也更差的东西。 - 多出来的余数扔掉,不折进去。
random() % 62不是均匀分布:4,294,967,296 除不尽 62,所以字母表开头那几个字符会摊上余数、出现得略多一些。这里的循环是:值落进余数区间就重新取。那点偏斜很小,照样不接受 —— 因为"微小的偏斜"正是一个生成器的统计指纹长成的样子。 - 约束之后还要洗牌。 要求"必须有一个大写、一个数字、一个符号"然后按顺序把它们排在开头,会让每个密码长得一模一样。这里是先把字符取完,再用一次同样走拒绝采样的 Fisher–Yates 洗牌打乱位置。
比特数在这里指什么
对生成的密码,这道算术是老实的:长度 × log₂(候选池),所以 20 个字符配 94 个字符的池是 131 比特。每个位置确实都是从这 94 个里等概率取的,所以空间有多大就是多大。
对你自己输入的密码,同一个公式是天花板,不是测量值。Password123! 用了四类字符、12 个长度,按它实际抽样的那 63 个字符去乘是 72 比特左右 —— 可它在任何像样的词库攻击里都排在前一千个候选里,因为它根本不是从 63 个符号里随机抽的,它是一个单词加了后缀。所以测量表同时印出字母表估计和"你其实只用过这些字符"那一个版本,并把真攻击者在穷举之前就会先枚举的花样标出来:重复串、abcd 这种递增串、键盘上的一行、四位数年份。
表里那两个速度
猜测次数是一回事,每秒能猜多少次是另一回事。这张表故意取两个相反的速度:
- 每秒 10¹¹ 次代表一批 GPU 在打一个已经拖走的、未加盐的快速散列文件(NTLM,或把 MD5/SHA 当密码散列用的那种)。这是人们说"几秒就破解了"时心里的数字。
- 每秒 10⁴ 次代表一个会限流、会锁账号、也从不把散列交出去登录表单。同一个密码在那边一下就好七个数量级。
一个用 Argon2id 或 bcrypt 正经配置过的站点,连第一个数字都要小得多,因为哈希是故意做得费工的。这就是为什么印出来的是时间而不是一根颜色条:颜色条意味着网站怎么配置是已知的,而它不是。
什么都不保存,屏幕就是那个存储
什么都不保存。生成过什么不会被写进任何存储,历史活不过一次刷新,也没有任何东西被发出去:字符是在这个标签页的脚本里从候选池拼出来的,所以你输入的内容不会离开这台设备。候选会一直显示在屏幕上,直到你按清空或者重新生成 —— 这是有意的,但也意味着屏幕本身就是那个存储。把要用的那条放进你的密码管理器,然后重新生成一次。
问答
Q:我该按复制按钮,还是自己敲? 剪贴板和这台机器上所有其他程序共享,所以粘贴密码是一次真实但很小的暴露,复制之后那条提示说的就是这一点,而不是假装剪贴板是私密的。自己敲更严格;管理器的自动填充是两者里最好的。
Q:长度真的比符号有用吗?
是,而且能算出来。20 个字符配 94 池,多一个字符就是多 6.5 比特;而在一个限制长度的站点上硬加符号类是要拿长度换的。六个词的骰子口令比 Xq7!pL2@ 结实,原因就是这个:空间更大,而不是它更好看。
Q:为什么勾上"去掉容易看混的字符"之后候选池就变了? 因为那十个字符不再是可选项,池子缩小,每字符的比特也就跟着降。如果你会在某个别扭的地方手打这个密码,这笔交换值得;如果由管理器填充,就不值得。
Q:“每个字符集至少一个"为什么是可选项? 它是给那些硬性要求的网站留的口子,不是强度特性。一个从完整候选池里随机取的 20 字符密码本来就大多数时候已经含齐了这些类;强行安排只是从一个本来不会缺类的密码上再拿走一点熵。
Q:我生成 50 条,挑最好的那条行不行? 它们强度完全相同,因为每一条都是用同一种方式取的,所以"最好"在这里没有意义。用第一条。如果某个网站拒绝它,就把那个网站拒绝的字符填进"永远不要用"框里重新生成,而不是手动改字符 —— 手改正是花样产生的地方。