这个页面的代码没跑起来。

直接从文件夹里打开 index.html,浏览器会拦下 JavaScript 模块,于是你选好长度之后,页面不会有任何反应。改用 http 把这个文件夹提供出去:

powershell -ExecutionPolicy Bypass -File serve.ps1

然后打开 http://localhost:8080/。

密码与密码短语 — 强随机,在你的浏览器里生成

在这里生成,由你自己的浏览器生成,不发往任何地方。什么都不保存,也没有历史记录。

语言: 简体中文
查看源码
你的密码和密码短语在浏览器里处理,无须上传处理。

每一个字符都来自 crypto.getRandomValues,也就是浏览器自带的加密随机数,每一个词都来自这个文件夹里的 src/wordlist.js。src/ 里没有 fetch,没有 XMLHttpRequest,也没有 sendBeacon,所以在这里生成的密码没有任何路径能到我们这儿,也到不了别人那儿。这里也不保存,刷新一下页面,它给你看过的密码就全没了。

实时检查: 检查中…

离线: 检查中…

不用听我们说。打开开发者工具,盯着网络面板,然后想按多少次再生成一个就按多少次。没有一个请求带走结果里的任何一个字符。或者干脆断网,接着生成。

1 选择生成什么

密码是一串字符:短、强,而且是你会放进密码管理器里的东西。密码短语是从词表里随机挑出来的一串词:敲起来长一些,但好记得多,也念得出口,正好用在那几个必须你自己从脑子里敲出来的秘密上,比如密码管理器自己的密码、笔记本电脑的密码、手机的恢复码。

2 设置

长度 长度胜过其他一切。往一个 94 个字符的字符集里多加一个字符,比任何关于必须包含哪些字符的规则都值钱。

用哪些符号 就是这些:。空格、两种引号、反引号和反斜杠在两组里都被特意排除了。它们和别的字符一样随机,但把一个本来好好的密码变成一张工单的,往往就是它们。

每一类至少一个字符 给那个非要不可的注册表单用的。它让密码更弱而不是更强,因为它把原本可能出现的一部分密码排除掉了。下面的读数已经把这一点减掉了。

不要容易看混的字符 去掉 I l 1 | 和 O 0,适合那种要从屏幕上读出来、再敲到别处去的密码。多加一两个字符的长度来补上这个代价。

词数 四个词是那张有名的图,放到今天已经低于值得用的水平。要紧的东西,六个词是合理的下限;守着其他所有密码的那一个,用七个。

词表 长表是每个词掷五次骰子,也就是 12.9 比特。短表是四次,10.3 比特,里面每个词都不超过五个字母,而且没有哪个词是另一个词的开头。要在电视遥控器上敲、或者从手机屏幕上读的密码短语,就用这一张。

词与词之间 这里面只有随机数字真的加了点东西,因为它在每个接缝处都是一次新的抽取,而不是一条规则。其余几个看的是你要粘进去的那个框收不收,空格最好读,也最容易被弄坏。

大写 这三个都不增加强度:当前用的是哪一个,谁都能从这个页面上读出来,攻击者不需要去猜。它放在这里,是给那种非要一个大写字母的表单用的。

结尾加一个符号 还是给那个较劲的表单用的。数字是一次真正的抽取,值 3.3 比特;符号是从八个里抽的,值 3 比特。

从哪些字符里抽

3 带走

或者一次生成好几个 下载的这份清单是一个纯文本文件,内容由这个页面从你屏幕上已有的东西写出来。保存它的是你的浏览器,存到的是你自己的硬盘,没有任何东西会把它送到别处去。话虽如此,硬盘上一个装满密码的文件仍然是一个装满密码的文件:把它们挪进密码管理器,然后把文件删掉。

— 比特的熵

攻击者要想确定找得到它,得把 — 种可能性都走一遍。

这个估计假定了什么

假定攻击者偷走了存放你密码的那个文件,正在自己的机器上以每秒一千亿次的速度往上撞。那大概相当于用一机架显卡去撞一个快速哈希,而泄露事件里反复出现的正是这种哈希。如果对面是一个挑得对的口令哈希,bcrypt 或者 Argon2,同样的机器每秒只能做几千次,上面每一个答案都会难上大约 25 比特。如果对面是一个每秒只回应十次的登录表单,那这些答案一个都够不着。

这个数字是特意取悲观那一头的,而且是要确定猜中所需的次数;平均一次攻击在一半的地方就找到答案,上面的估计用的正是这一半。

这里什么都不记

这个页面生成的东西从不保存、从不列出、从不发送。没有历史记录要清,是因为压根就没有在记:刷新一下页面,它给你看过的每一个密码就都没了,连它自己内存里的那份也没了。副本只有你自己留下的那些,也就是剪贴板,还有你要了的话那个文本文件。

以 Markdown 查看

怎样生成一个强密码,还不让任何网站看到

  1. 先选密码还是密码短语。密码是一串随机字符:存起来短,敲起来麻烦,正好适合那几百个由密码管理器替你填的账号。密码短语是从词表里随机抽出来的一串词:长一些,但记得住、念得出,这正是那几个必须你自己从脑子里敲出来的秘密所需要的,比如密码管理器自己的密码、笔记本电脑的密码、手机的恢复码。
  2. 定长度,或者定词数。这才是那个要紧的设置,其余的大多不是。值得保护的东西,20 个字符或者六个词是个合理的下限;那个能把其他所有密码都重置掉的账号,就从这里往上加。下面的读数会跟着你拖动一起变,所以多一个字符换来什么,你当场就能看见。
  3. 把注册表单会较劲的规则打开。“每类至少一个”、末尾一个数字、一个哪个网站都收的短名单里的符号。这些都不会让密码更强,第一个甚至让它稍微弱了一点,而这一点页面已经替你减掉了。但要不来回生成六个就通过注册表单,靠的就是它们。
  4. 看数字,别看颜色。比特数是从生成这串字符的设置里数出来的:字符集有多大,抽了多少次,就这些。这是一次真正的测量,跟注册页上那根条不一样。那根条只能给眼前的字符打分,没有办法知道这些字符是你选的还是生成器选的。
  5. 走之前先复制,先放好。这里没有历史记录,也没有办法再要回来,刷新页面它就没了。先粘进密码管理器,再粘进注册表单,让需要记住它的那一头先拿到手,中间出什么岔子都不怕。
  6. 要一批就一次生成一批。最下面那个滑块一次最多生成一百个,还能存成纯文本文件,内容就是页面从你屏幕上已有的东西写出来的。批量开账号或者发初始口令时好用,等它们进了更合适的地方,这个文件就该删掉:硬盘上一个装满密码的文件,仍然是一个装满密码的文件。

说得更细的版本

用在线密码生成器安全吗? 这份疑心是对的,值得认真对待:浏览器的随机数从哪儿来,一个生成页面可能错在哪儿,以及哪些检查能看出眼前这个页面留没留它造出来的东西。

常见问题

密码会被发到什么地方,或者被保存下来吗?

密码在这个浏览器里生成,工具代码不上传密码,也不保存密码历史。复制或保存由你选择。共享页面框架可以保留本地偏好和临时语言切换设置,但不包含生成的密码输出。CSP 限制目的地,不能证明已允许请求的内容。请读代码并检查操作的流量。

随机数是从哪儿来的?

来自 crypto.getRandomValues,浏览器为密码学用途提供的随机数,由你自己操作系统的熵池播种并不断重新播种。浏览器取 TLS 密钥材料用的也是同一个来源。这个工具里任何地方都没有用 Math.random,这个区分不是抠字眼:Math.random 是一个很快的算术随机数,它的整个内部状态能从连续几个输出里还原出来,建立在它上面的密码生成器产生的密码只是看起来随机,任何见过其中一个的人都能把其余的全部列举出来。

浏览器里生成的密码,和装在电脑上的程序生成的一样好吗?

就随机数而言是一样的,两边都是操作系统的同一个来源,只是走的门不同。不同的是屋子里还有谁。浏览器标签页是和你的扩展一起运行的,一个有权限读页面的扩展也能读这一页。这对任何网页上的生成器都成立,包括这一个,也正是“手边有密码管理器时就用它自带的生成器”这条建议的诚实理由:算术是一样的,只是那个进程旁边站的人少。这个页面是给你手边没有它的时候用的。

密码还是密码短语,到底该用哪个?

凡是密码管理器替你敲的,都用密码,因为你根本不会去看它,而长度在那里是白送的。那几件必须你自己从脑子里敲出来、或者念给别人听的,用密码短语:管理器的主密码、磁盘加密的密钥、一台你远程配置的设备。长词表里六个词是 77 比特,比十二个字符的随机密码还强,而且凌晨四点也能一次输对,这一点差得不是一星半点。

密码该有多长?

全字符集下 20 个字符大约是 130 比特,早就过了还需要担心长度的那个点。16 个也很够。12 个是任何你不想丢的东西的下限,而且是下限,不是目标。再短,你就是在赌那个网站把它妥善存了起来,而过去二十年的泄露通知劝你别赌。长度胜过这个页面上任何别的设置:多一个字符,比任何关于必须包含哪些字符的规则都管用。

密码短语该用几个词?

长词表里六个词,如果它守着别的密码就七个。那张著名的四个词的图是 2011 年画的,值 51 比特,今天已经在一次认真的离线攻击的射程之内。五个词是 64,六个词是 77,超过了攻击者会为一个普通账号花的代价。长词表里每多一个词就多 12.9 比特,而且只有词在往上加,连字符和大写字母都不加。

什么是“比特”,这个页面为什么要数它?

一个比特就是翻一倍。60 比特的意思是,这个页面本来可能产生的、概率相同的结果有 2^60 种,所以就算有人完全清楚它是怎么工作的,也还是有这么多要试。这是过程的性质,不是这串字符的性质:页面能把它说准,是因为选的人就是它,它知道自己选了多少次。这就是它和注册表单上那根彩色条的区别,那根条只是读了字符然后猜。在那根条上,correct horse battery staple 评分很差,实际值 44 比特;P@ssw0rd! 评分很好,实际几乎一文不值。

为什么“必须包含一个符号”反而让密码变弱?

因为规则只能拿走可能性。要求每一类至少出现一个字符,就把所有恰好没抽到的密码全排除掉了,而可能的密码这个集合越小,要搜的范围也越小。影响不大,常见长度下大约半个比特,但它是真实存在的,而这个页面把它减掉了,没有去报那个对自己更好看的数。而且是精确算出来的:数的是这条规则真正允许的密码,而不是它排除掉的。

这是哪个词表,攻击者能下载到它要紧吗?

是电子前哨基金会(EFF)的 diceware 词表,原样打包进来:长的 7776 个词,短的 1296 个。它们本来就是为这件事做的:没有冒犯性的词,没有同音词,没有连起来会变成第三个词的组合,短表里也没有哪个词是另一个词的开头。至于词表是公开的,不要紧:这里给出的强度本来就假定攻击者手里有这份表,正在读这个页面的源码,还知道你用的每一项设置。他唯一不知道的,是每一次抽中的是 7776 个里的哪一个。正是这个假定,让这个数字值得信。

密码短语不就是等着被字典攻击吗?

按这种方式选词就不是。字典攻击对付的是人想出来的短语,因为人挑的词彼此搭调、顺序讲得通,而且来自自己每天用的那几千个词。这个页面是从一份固定的词表里,一个词一个词独立地、均匀地抽,完全不管结果读起来顺不顺,所以它通常读起来并不顺。一个知道词表也知道词数的攻击者,面前仍然是 7776 的词数次方。

离开页面之后还能把密码找回来吗?

找不回来,而且是故意的。任何地方都没记下来,所以没有什么可找的:没有历史面板,没有“最近生成”列表,也没有缓存。一个能把上周二的密码翻给你看的生成器,就是一个把它存下来了的生成器,而存在你够得着的地方,也就是存在别的东西够得着的地方。离开之前先复制到密码管理器里。

复制到剪贴板安全吗?

这是常见的那一类风险,知道它比担心它有用。剪贴板和所有以你身份运行的程序共享,通常会留到你下一次复制,有些配置下还会在设备之间同步。所以该粘的地方立刻粘,粘完再随便复制点别的,这是好习惯;但这不构成改用手敲一个更弱密码的理由。这个页面读不到你的剪贴板,它只能往里写,而且只在你按下按钮的时候写。

同一个能在多个地方用吗?

不能,而这是这个页面上唯一一条压过其他所有建议的建议。几乎每一个被盗的账号,用的都是先在别处对过的密码:某个网站被攻破,名单被公开,同样的邮箱配同样的密码被拿到各处去试。一个网站一个密码,能把一次泄露变成一个账号而不是全部,这才是值得用密码管理器的理由,而不是它里面某一个密码有多强。

免费吗?要注册账号吗?

免费,没有账号,不用登录,没有试用期,生成多少个都不限。网站靠广告养着,而广告拿不到关于这个页面生成的东西的任何信息,长度和强度都拿不到。

离线能用吗?

能。把页面加载一次,然后断开网络,它照样生成密码。随机数来自你自己的设备,词表本来就在页面里。这也是证明它既没在取什么、也没在发什么的最简单办法:一个要向服务器要数字的生成器,在你拔线的那一刻就会停下来。