# 密碼與密碼短語 — 強隨機，在你的瀏覽器裡產生

在這裡產生，由你自己的瀏覽器產生，不發往任何地方。什麼都不儲存，也沒有歷史記錄。

> 產生一個強隨機密碼，或者用頁面內建的 7776 個詞的詞表產生一條 diceware 密碼短語。由瀏覽器自身的加密隨機數產生，不發往任何地方，也不儲存。免費，不用註冊。

本頁是一個完全在你的瀏覽器裡執行的互動式工具，地址是 https://abox.tools/zh-TW/password-generator/。你交給它的任何內容都不會被上傳。下面是這個頁面用文字對該工具的全部說明；要使用它，請開啟這個地址。

## 你的密碼和密碼短語**不會上傳**。這裡根本沒有伺服器。

每一個字元都來自 `crypto.getRandomValues`，也就是瀏覽器內建的加密隨機數，每一個詞都來自這個資料夾裡的 `src/wordlist.js`。`src/` 裡沒有 `fetch`，沒有 `XMLHttpRequest`，也沒有 `sendBeacon`，所以在這裡產生的密碼沒有任何路徑能到我們這裡，也到不了別人那裡。這裡也不儲存，重新整理一下頁面，它給你看過的密碼就全沒了。

- ✗ 不上傳
- ✗ 不用帳號
- ✗ 不儲存
- ✓ 離線可用
- ✓ 原始碼公開

## 怎樣產生一個強密碼，還不讓任何網站看到

1. **先選密碼還是密碼短語。** 密碼是一串隨機字元：存起來短，敲起來麻煩，正好適合那幾百個由密碼管理器替你填的帳號。密碼短語是從詞表裡隨機抽出來的一串詞：長一些，但記得住、念得出，這正是那幾個必須你自己從腦子裡敲出來的秘密所需要的，比如密碼管理器自己的密碼、膝上型電腦的密碼、手機的恢復碼。
2. **定長度，或者定詞數。** 這才是那個要緊的設定，其餘的大多不是。值得保護的東西，20 個字元或者六個詞是個合理的下限；那個能把其他所有密碼都重置掉的帳號，就從這裡往上加。下面的讀數會跟著你拖動一起變，所以多一個字元換來什麼，你當場就能看見。
3. **把登入表單會較勁的規則開啟。** 「每類至少一個」、末尾一個數字、一個哪個網站都收的短名單裡的符號。這些都不會讓密碼更強，第一個甚至讓它稍微弱了一點，而這一點頁面已經替你減掉了。但要不來回產生六個就透過登入表單，靠的就是它們。
4. **看數字，別看顏色。** 位元數是從產生這串字元的設定裡數出來的：字符集有多大，抽了多少次，就這些。這是一次真正的測量，跟註冊頁上那根條不一樣。那根條只能給眼前的字元打分，沒有辦法知道這些字元是你選的還是產生器選的。
5. **走之前先複製，先放好。** 這裡沒有歷史記錄，也沒有辦法再要回來，重新整理頁面它就沒了。先貼進密碼管理器，再貼進登入表單，讓需要記住它的那一頭先拿到手，中間出什麼差錯都不怕。
6. **要一批就一次產生一批。** 最下面那個滑塊一次最多產生一百個，還能存成純文字檔案，內容就是頁面從你螢幕上已有的東西寫出來的。批次開帳號或者發初始口令時好用，等它們進了更合適的地方，這個檔案就該刪掉：硬碟上一個裝滿密碼的檔案，仍然是一個裝滿密碼的檔案。

## 工具箱裡還有

- [JSON 格式化](https://abox.tools/zh-TW/json-formatter/): JSON、XML、HTML、CSS 和 YAML，格式化或轉換。沒有一個字被貼進別人的伺服器。
- [YAML 轉 JSON](https://abox.tools/zh-TW/yaml-to-json/): 兩個方向都有，而且會告訴你各自的代價。這些都不會貼進別人的伺服器。
- [XML 格式化](https://abox.tools/zh-TW/xml-formatter/): 排開了好讀的 XML，壓平了好發的 XML，還有兩個方向的 JSON 轉換。這些都不會貼進別人的伺服器。
- [文字比對](https://abox.tools/zh-TW/text-diff/): 兩段文字進來，每處差異都被標出來，逐行、逐詞。沒有一個字被貼進別人的伺服器。

## 常見問題

### 密碼會被髮到什麼地方，或者被儲存下來嗎？

都不會。它們在你的瀏覽器裡、你自己的機器上產生，而這個工具根本沒有任何聯網功能，從不去取什麼，也從不傳送什麼。它也不往儲存裡寫任何東西：沒有 localStorage，沒有 Cookie，沒有歷史記錄。重新整理頁面，它給你看過的密碼就從螢幕上、也從它自己的記憶體裡消失了。頁面的 `Content-Security-Policy` 寫著它允許連線的每一個地址，沒有一個是我們的，所以就算有什麼想送出去，也沒有地方收。

### 隨機數是從哪裡來的？

來自 `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 的詞數次方。

### 離開頁面之後還能把密碼找回來嗎？

找不回來，而且是故意的。任何地方都沒記下來，所以沒有什麼可找的：沒有歷史面板，沒有「最近產生」列表，也沒有快取。一個能把上週二的密碼翻給你看的產生器，就是一個把它存下來了的產生器，而存在你夠得著的地方，也就是存在別的東西夠得著的地方。離開之前先複製到密碼管理器裡。

### 複製到剪貼簿安全嗎？

這是常見的那一類風險，知道它比擔心它有用。剪貼簿和所有以你身份執行的程式共享，通常會留到你下一次複製，有些配置下還會在裝置之間同步。所以該貼的地方立刻貼，貼完再隨便複製點別的，這是好習慣；但這不構成改用手敲一個更弱密碼的理由。這個頁面讀不到你的剪貼簿，它只能往裡寫，而且只在你按下按鈕的時候寫。

### 同一個能在多個地方用嗎？

不能，而這是這個頁面上唯一一條壓過其他所有建議的建議。幾乎每一個被盜的帳號，用的都是先在別處對過的密碼：某個網站被攻破，名單被公開，同樣的信箱配同樣的密碼被拿到各處去試。一個網站一個密碼，能把一次洩露變成一個帳號而不是全部，這才是值得用密碼管理器的理由，而不是它裡面某一個密碼有多強。

### 免費嗎？要註冊帳號嗎？

免費，沒有帳號，不用登入，沒有試用期，產生多少個都不限。網站靠廣告養著，而廣告拿不到關於這個頁面產生的東西的任何資訊，長度和強度都拿不到。

### 離線能用嗎？

能。把頁面載入一次，然後斷開網路，它照樣產生密碼。隨機數來自你自己的裝置，詞表本來就在頁面裡。這也是證明它既沒在取什麼、也沒在發什麼的最簡單辦法：一個要向伺服器要數字的產生器，在你拔線的那一刻就會停下來。

## 這條隱私承諾怎麼核實

- **密碼就在你讀這行字的地方產生。** 它在這個頁面裡，由這個頁面，從你自己的作業系統交給瀏覽器的隨機數中抽出來。產生它不需要去取任何東西，產生完也不會上報任何東西。`Content-Security-Policy` 裡寫著這個頁面允許連線的每一個地址，沒有一個是我們的。這裡沒有一個可以收集產生出來的密碼的落點，就算有，程式碼裡也沒有把它送過去的那一行。
- **這裡沒有任何東西會去取東西。** `src/` 裡沒有 `fetch`，沒有 `XMLHttpRequest`，也沒有 `sendBeacon`。詞表不是下載來的，它就是 `src/wordlist.js`，跟頁面其他部分一起從這個來源送出，你可以開啟來看。
- **隨機數是瀏覽器的，而且是對的那一種。** `crypto.getRandomValues` 是瀏覽器為金鑰和令牌提供的隨機數，由作業系統播種，並且不斷重新播種。`Math.random` 在這個資料夾裡一次都沒有出現過，出現了才是真正的缺陷：它的內部狀態能從幾個輸出裡還原出來，誰看過它產生的一個密碼，就能算出它以後會產生的每一個。
- **什麼都不儲存，所以沒有歷史記錄要清。** 沒有 localStorage，沒有 sessionStorage，沒有 Cookie，沒有 URL 引數，也沒有瀏覽器會主動提出記住的 `<input>`。螢幕上的東西只活在這個頁面記憶體裡的一個陣列中，關掉分頁就是全部的清理。這裡產生的東西，只有你帶走的那些副本。
- **谷歌載入了什麼，又拿不到什麼。** 廣告和統計指令碼來自谷歌，捐贈按鈕來自 Buy Me a Coffee。它們誰都拿不到這個頁面產生的任何一個字元，也拿不到長度、強度，以及是用哪些設定產生的。每一行抽取字元或詞的程式碼都從這個來源送出，都在儲存庫裡。
- **它離線可用。** 斷開網路，這個工具一點沒變，因為它裡面從來就沒有過一步聯網。這是最簡單的證明：一個要向伺服器要隨機數的產生器，在你拔線的那一刻就會停下來。

**你可以自己核對。**上面這些不用你信。這個頁面是儲存庫裡的模板和配置產生出來的，構建指令碼你能讀，也能自己跑一遍，跑出來的結果就提交在 `dist` 分支上。拿實際發給你的內容，跟你自己從原始碼構建出來的結果對一遍就知道了： https://github.com/A-Box-of-Tools/website

最值得先讀的幾個檔案：`config/site.toml` 裡是 Content-Security-Policy，`src/random.js` 是這個頁面和它產生的每一個密碼之間的那四十行，它只有一個輸入，就是瀏覽器自己的隨機數；`src/generate.js` 是設定怎麼變成一串字元；`src/strength.js` 是那個數字背後的算術，它是在數，不是在猜。
