密碼產生器 API 替代方案指的是任何一種工具,能在不向遠端端點發送請求的情況下產生強而隨機的密碼。開發人員與 IT 團隊最常搜尋這類工具的原因,在於 API 會帶來摩擦:需要管理的 API 金鑰、必須遵守的速率限制、在不穩定的網路上會失敗的呼叫,以及一個可能記錄你的請求、調整定價或直接關閉服務的第三方。「當個人用」瀏覽器內建的 crypto.getRandomValues() 所打造的產生器,可以徹底消除上述所有疑慮,因為隨機性來自你自己的裝置,而密碼從未離開過分頁。這讓由本機 CSPRNG 支援的工具,在多數工作流程中都能直接取代密碼產生器 API——無論是在 CI 管道中建立測試使用者,還是為共用服務交付一組強密碼給同事。其密碼學保證與伺服器端的 CSPRNG 完全相同,差別只在於:什麼都不會被傳送、儲存或受到速率限制。

為什麼開發人員選擇密碼產生器 API(以及它們的不足之處)
密碼產生器 API 之所以流行,是因為它們能把一件工作做得很好:透過 HTTP 產生一組隨機字串。你送出描述長度與字元集的請求,伺服器就會回傳一組由強化版 CSPRNG 產生的密碼。這種模式能乾淨地整合進伺服器端程式、自動化腳本,以及本來就在用 HTTP 溝通的 CI 工作流程,因此團隊將它視為擺脫測試 fixture 中 password123 最簡單的方法。
但同樣的模式在以下幾個常見情境中會失靈:
- 速率限制。免費方案會限制每分鐘的請求數,而管道中一個行為異常的迴圈,可能在真正的測試執行前就把配額燒光。
- API 金鑰管理。每個 API 都需要憑證,這代表環境變數中有秘密、需要輪替政策,以及金鑰在工作中過期時偶爾冒出來的 401 錯誤。
- 網路依賴。隔離網路的建置主機、離線筆電,以及有流量限制的行動連線,都會讓純 API 的工作流程中斷。
- 隱私曝露面。API 提供者會看到你送出的參數,也可能加以記錄。對內部憑證或敏感的測試資料來說,這是實實在在的稽核疑慮。
- 供應商風險。公開 API 會變更端點、棄用版本,甚至直接消失。今天還能跑的整合,下一季可能就變成死碼。
這些問題都不能成為放棄強隨機密碼的理由。它們只是說明:值得考慮不同的傳遞機制——一個在發出請求的同一台機器上執行的產生器,這樣根本不需要發出請求。
瀏覽器型密碼產生器實際做了什麼
這個 密碼產生器 完全在瀏覽器分頁中執行。沒有需要驗證的端點、沒有會被觸發的速率限制,也沒有任何伺服器記錄會留下你的輸出。當你按下「產生」,頁面會呼叫瀏覽器內建的密碼學亂數產生器,並從你選定的字元集中均勻抽取每個字元。點選「複製」即可把結果放到剪貼簿。
在底層,有三個細節值得注意:
- 隨機性的來源是 crypto.getRandomValues(),它正是驅動 TLS、WebCrypto 金鑰產生,以及安全 Cookie 的同一個 CSPRNG。根據 MDN 的參考文件,它回傳的值取自一個不可預測且適用於密碼學用途的來源。
- 每個字元是透過拒絕抽樣而非單純的模數運算選出,因此集合中的任何字元都不會在統計上被偏好。若有模數偏誤,攻擊者就能利用輸出中細微的偏好來縮減搜尋空間。
- 保證至少包含每個啟用類型的一個字元,並使用 Fisher–Yates 演算法把最終字串打亂,避免那些保證出現的字元被固定在特定位置。
這三項特性加在一起,能產生一組實際熵值符合「長度 × log₂(字元池)」計算結果的密碼,而不是因為偏誤或較弱的 RNG 而略遜一籌的版本。
在瀏覽器中產生一組強密碼
- 開啟密碼產生器,使用滑桿或數字框設定長度。16 個字元是合理的預設值,長度愈長愈好。
- 切換你想要的字元類型:大寫、小寫、數字、符號。全部啟用可得到最大的字元池(86 個字元)。
- 可以勾選「排除易混淆字元」,以便在你要手動輸入密碼時排除 0、O、1 與 l。
- 查看欄位旁顯示的強度與熵值估計。低於 60 位元屬於偏弱,60–100 之間為普通,超過 100 則對離線暴力破解攻擊具有強抵抗力。
- 按 複製 把密碼放到剪貼簿,或再按一次 產生 重新抽一組。用完後關閉分頁,因為什麼都沒有被儲存在任何地方。
對於需要密碼卻不能使用瀏覽器的自動化工作流程,同樣的邏輯可以在 Node.js 或 Deno 中以 crypto.getRandomValues() 或 crypto.randomBytes() 重現。只有當你需要給真人使用的 UI 時,「API 替代方案」這個議題才有意義。
CSPRNG vs Math.random:真正的安全性差距
JavaScript 的 Math.random() 雖然快速又方便,但它並不具備密碼學安全性。它的內部狀態很小,只要看過少數先前的輸出,攻擊者就能預測接下來的結果。NIST SP 800-63B 與 OWASP 驗證備忘錄都警告不要將非密碼學 RNG 用於秘密,因為輸出呈現的熵會高於實際的不可預測性。
像 crypto.getRandomValues() 這類 CSPRNG 的設計目標,是讓擁有任意先前輸出的觀察者也無法以比暴力破解更快的方式算出未來輸出。從 86 字元池中抽出 16 個字元的密碼,長度對應的熵約為 103 位元,這代表對字串一無所知的攻擊者必須面對大約 2¹⁰³ 次猜測——這個數字大到足以讓離線暴力破解攻擊不切實際。如果把 CSPRNG 換成 Math.random(),那 103 位元的主張就會瞬間崩塌,變成攻擊者能建模並更有效率破解的目標。
影響熵最大的單一槓桿是長度,而不是字元多樣性。把長度從 16 個字元加倍到 32 個字元,大致會讓熵的位元數翻倍,因為每多一個字元,攻擊者必須做的工作就會倍數成長。相比之下,把數字換成符號,只會把字元池從 62 變成 86——這是有意義但較小的提升。這就是為什麼現代指引偏愛長的 passphrase 或隨機字串,而不是那種把幾個符號硬塞進短密碼的強制複雜度規則。
密碼產生器 API vs 瀏覽器工具:並排比較
| 屬性 | 託管式 API | 瀏覽器型產生器 |
|---|---|---|
| 需要網路呼叫 | 每次產生都需要 | 不需要 |
| API 金鑰或驗證 | 大多數提供者都要求 | 不適用 |
| 速率限制 | 免費方案常見 | 無 |
| 離線使用 | 不可能 | 頁面載入後即可 |
| 熵的來源 | 伺服器端 CSPRNG | 瀏覽器 crypto.getRandomValues() |
| 輸出會送到哪裡 | 傳輸到用戶端,可能被記錄 | 停留在瀏覽器分頁中 |
| 供應商綁定 | 受制於提供者的路線圖 | 無外部相依性 |
| 稽核與合規 | 取決於提供者 | 完全在本機且可檢視 |
兩個欄位提供的是相同的密碼學基元——從選定字元池中均勻抽出的隨機字串——但瀏覽器版本能在沒有整合營運負擔的情況下交付它。
實作範例:16 字元密碼的熵
為了把熵的計算講得更具體,以啟用全部四種字元類型、16 個字元的密碼為例。字元池大小為 86,因此每個字元貢獻約 log₂(86) ≈ 6.426 位元。長度乘以每字元的熵,得到 16 × 6.426 ≈ 102.8 位元,工具會四捨五入為約 103 位元。這個單一數字就是攻擊者必須克服的關鍵指標,而且它隨長度線性成長:同一字元池下的 24 字元密碼約為 154 位元,32 字元密碼約為 206 位元。換句話說,把長度加倍,攻擊者的工作量也加倍。
本機產生器勝過 API 的時機
只要 API 的營運成本超過它帶來的便利,「密碼產生器 API 替代方案」就有意義。這涵蓋了相當多的場景:
- 個人使用。為新帳號產生一組強密碼,並不值得繞道去呼叫第三方服務。
- 離線或受限環境。隔離網路的工作站、安全飛地,以及受到嚴格限制的瀏覽器,都無法連到 API,但能執行本機 JavaScript。
- 重視隱私的工作流程。用於預備環境、客戶入口或合規展示的內部憑證,不應該出現在任何第三方的存取記錄中。
- 快速示範與教學。在 Chrome 中無需同步即可執行產生器的指南展示了如何在全新的設定檔中產生強密碼,不需帳號、不需擴充功能、也不留任何儲存資料。
- 教學 CSPRNG 概念。向學生或部落格讀者展示一組均勻隨機字串究竟是如何建構的——拒絕抽樣、Fisher–Yates、熵的計算——使用一個可以檢視原始碼的工具,會容易得多。
對於高流量的伺服器端工作負載——例如在建置管道中每秒產生數千組測試密碼——API 仍有其位置,因為你可以把一次網路呼叫攤提到多次輸出。但對於一次性的人工使用,或任何隱私、延遲、可靠性的重要性高於 HTTP 便利性的情境,瀏覽器型密碼產生器是更簡潔的答案。
如果你正在權衡選項,在 JavaScript 中檢查密碼長度:程式碼與本機稽核對此有詳細說明。