Command Palette

Search for a command to run...

Bcrypt 的工作原理:鹽、成本因素和限制

Bcrypt 的工作原理:鹽、成本因素和限制

T
Toolz Team
|Sep 13, 2026|17 閱讀
在 Google 上首選 Toolz。dev

安全 系列的一部分

Bcrypt 產生器

在瀏覽器中產生並驗證 bcrypt 密碼雜湊值,並具有可調整的成本係數

使用Bcrypt 產生器

當我第一次發布登入系統時,我做了那個時代每個教學告訴我的事情:儲存 md5($password) 在用戶表中並繼續前進。它起作用了,這悄悄地是一場災難。多年後將 auth 建置到 WordPress 外掛程式和 Laravel 應用程式中,我對 &quot 之間的差距有了更健康的尊重;密碼檢查通行證和報價;和&報價;如果資料庫洩漏,密碼是安全的。&報價; Bcrypt 是縮小大部分差距的工具,也是我接觸到的幾乎每個框架的預設值。所以我建立了一個 bcrypt 產生器 在 工具。dev 它會使用您控制的成本係數對密碼進行雜湊處理,根據現有雜湊驗證密碼,並在瀏覽器中執行所有操作,因此您輸入的任何內容都不會發送到任何地方。這是它和 bcrypt 本身的指南。

TL;DR: Bcrypt 將密碼轉換為加鹽的、故意減慢的 60 個字元雜湊值,因此洩漏的資料庫不是洩漏的密碼清單。工具 bcrypt 產生器 使用可調整的成本係數(4 到 31)對任何密碼進行雜湊處理,根據您貼上雜湊值驗證密碼,並顯示其解析的版本、成本和鹽分。它產生標準 $2b$ openbsd、php 格式 password_hash,Laravel 和 Node bcrypt 庫都接受,並且它完全運行客戶端。

什麼是 bcrypt?

Bcrypt 是一種密碼雜湊函數,由 Niels Provos 和 David Mazieres 設計,並在他們 1999 年的 USENIX 論文中提出 &引用;未來適應性密碼方案和引用;. 它建立在 Blowfish 分組密碼的基礎上,但有一個轉折:它不是加密數據,而是運行 Blowfish'使用密碼和隨機鹽作為金鑰材料,一遍又一遍地執行金鑰設定步驟。結果是一種單向雜湊,計算一次便宜,計算十億次昂貴,這正是屬性密碼儲存的需要。

那&報價;目的和報價都很昂貴;想法是它的核心。像 SHA-256 這樣的通用雜湊被設計為快速的,因為校驗和和完整性檢查需要速度。密碼雜湊想要相反的結果。如果攻擊者竊取了您的資料庫,那麼它們和每個明文密碼之間唯一存在的就是猜測需要多長時間。快速雜湊可以讓現代 GPU 每秒測試數十億個候選者; bcrypt 雜湊的合理成本上限為每核心每秒數千個。相同的洩漏文件,截然不同的結果。

Bcrypt 已經存在了二十多年,因為它的基本原理是正確的,而且具有適應性。成本係數意味著可以為 1999 年硬體調整的相同演算法可以在 2026 年硬體上撥號,而無需更改任何其他內容。它仍然是推薦的選項 OWASP 密碼儲存備忘單,這是 Laravel、Spring Security 和我工作的許多其他堆疊中的開箱即用預設值。如果您想要更深入的背景來了解為什麼快速哈希對於這項工作是錯誤的,那麼 資料隱私線上工具 該指南涵蓋了推動整個行業走向緩慢、鹹味哈希的推理。

bcrypt 哈希包含什麼?

bcrypt 最好的事情之一是它的輸出是自描述的。取一個真正的哈希值:

$2b$12$R9h/cIPz0gi.URNNX3kh2OPST9/PgBkqquzi.Ss7KIUgO2t0jWMUW

從左到右閱讀,在美元符號上分割,它會告訴您驗證密碼所需的一切:

田野 例子 意義
版本 2b bcrypt 變體。 2b 是目前更正的 OpenBSD 格式
成本 12 工作因素。金鑰設定運行 2^12 = 4096 次迭代
鹽 R9h/cIPz0gi.URNNX3kh2O 22 個自訂 Base64 字符,解碼為 16 個隨機位元組
摘要 PST9/PgBkqquzi.Ss7KIUgO2t0jWMUW 31 個字元編碼 23 位元組 bcrypt 輸出

因為鹽和成本存在於字串中,所以驗證不需要其他任何東西。當你將哈希值貼到其中時 bcrypt 產生器 驗證模式,它直接從字串中讀取成本和鹽,用精確的鹽重新計算摘要,然後進行比較。沒有單獨的鹽列需要管理,這也是 bcrypt 儲存起來如此愉快的原因之一:它是使用者表中的一個不透明欄位。

自訂 Base64 字母表值得一提,因為它會讓人絆倒。 Bcrypt 使用 ./A-Za-z0-9,這與標準 Base64 的順序不同。 bcrypt 鹽不是標準 Base64 字串,因此請勿嘗試使用通用 Base64 工具對其進行解碼並期望有意義的位元組。如果您對其他地方使用的標準變體感到好奇,那麼 base64 編碼 指南瀏覽普通字母表及其顯示的位置。

如何產生 bcrypt 哈希?

在該工具中,它分為三個步驟:輸入密碼、選擇成本、按一下「產生」。在引擎蓋下,產生雜湊值的作用比看起來更多。首先,使用 Web Crypto API 建立 16 位元組的加密強隨機鹽。然後 bcrypt 運行其昂貴的金鑰計劃,使用密碼和鹽播種 Blowfish 並迭代 2^cost 時間。最後,它使用產生的密碼狀態對固定魔弦("OrpheanBeholderScryDoubt")進行 64 次加密,並對輸出進行 Base64 編碼。整個舞蹈產生 60 個字元的雜湊值。

最常見的驚喜是,兩次散列相同的密碼會產生兩個不同的散列。這是正確且有意為之的。每個哈希都有自己的隨機鹽,因此兩個用戶都會選擇 hunter2 最終儲存的值完全不同。竊取表的攻擊者無法判斷兩個帳戶共用密碼,也無法跨帳戶重複使用預先計算的表。如果您想重現特定的雜湊值進行測試,您可以提供完整的鹽串而不是裸成本,這正是驗證模式在內部所做的。

在您的應用程式程式碼中,您永遠不會手動組裝其中任何一個。你打電話給圖書館:

// PHP
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
// Node with bcrypt / bcryptjs
const hash = await bcrypt.hash(password, 12)
// Laravel
use Illuminate\Support\Facades\Hash;
$hash = Hash::make($password); // bcrypt by default

Toolz 工具適用於該程式碼周圍的時刻:理智地檢查給定成本的雜湊值,為播種機或測試夾具產生已知的雜湊值,或確認您在配置中找到的雜湊值與您的密碼相符認為確實如此。

如何選擇成本因素?

成本因素是你必須考慮的一個旋鈕,誠實的答案是"測量,不要複製。&引用; OWASP 的經驗法則是,單一雜湊值在生產硬體上應該需要大約四分之一秒的時間。該目標平衡了兩種相反的力量:太低,你使破解變得便宜,太高,每個合法登入都付出代價,當繁忙的端點對每個請求進行雜湊處理時,這一點很重要。

因為成本是二的冪,所以每一步都會使工作加倍。成本 11 的速度是成本 10 的兩倍,成本 12 的速度是成本 10 的四倍。在典型的 2020 年代伺服器硬體上,成本 10 到 12 落在正確的鄰域,這就是框架預設的原因。該工具在拖曳滑桿時顯示粗略的時間估計,以便您可以感覺到成本複合的速度,但將其視為相對指南,而不是伺服器的基準。真實數字取決於您的 CPU,了解它的唯一方法是時間 password_hash 在運行它的盒子上。

一種值得了解的實用模式:因為成本儲存在每個雜湊中,因此您可以隨著時間的推移提高成本,而無需遷移。成功登入後,您會暫時掌握明文,因此您可以檢查儲存的雜湊值是否低於目前目標,如果是,則重新雜湊和更新。 PHP 直接公開了這一點 password_needs_rehash. 這意味著您的安全性與硬體保持同步,而無需強制重設密碼。

Bcrypt 與 SHA-256、Argon2 和 scrypt

最重要的比較是與普通快速雜湊和較新的記憶體硬函數的 bcrypt。以下是它們如何排列密碼儲存:

功能 醃製 故意放慢速度 記憶力強 適合密碼嗎?
MD5/SHA-256 不(本身) 不 不 不,太快了
bcrypt 是的,內建 是的,成本可調 不 是的,推薦
密碼 是的 是的 是的 是的
氬2id 是的 是的 是的 是的,首選新系統

裸露的 SHA-256 密碼,即使是加鹽的,也是錯誤的工具:它是為速度而設計的,因此洩漏的 SHA-256 哈希資料庫很快就會落入 GPU。如果您只需要校驗和或快取金鑰的快速摘要而不是密碼,那就是 哈希生成器 是為了,區別是重點。 2015 年密碼雜湊競賽的獲勝者 Argon2id 增加了記憶體硬度,它抵抗了可以加速 bcrypt 的自訂硬件,並且是控制運行時間的全新系統的首選。但 bcrypt 並沒有過時。它經過了戰鬥測試,是我每天使用的工具的預設值,選擇它是一個明智的決定,特別是當您的框架附帶它時。要避免的錯誤不是"bcrypt 而不是 Argon2,"它是"快速哈希而不是其中任何一個。"為了更廣泛地了解與哈希配對的安全實用程序, 開發人員生產力工具 導遊有地圖。

72 位元組限制和其他陷阱怎麼樣?

Bcrypt 只讀取密碼的前 72 位元組。任何過去被默默忽略的事情,這對普通密碼來說都無關緊要,但可能會咬住很長的密碼,尤其是具有多位元組UTF-8 字元的密碼,其中位元組計數爬升速度快於字元計數。每當您的輸入超過 72 個 UTF-8 位元組時,該工具就會向您發出警告,因此截斷永遠不會是一個無聲的驚喜。有些系統會繞過限制,在將密碼交給 bcrypt 之前使用 SHA-256 和 Base64 對密碼進行預先雜湊,然後將其折疊為固定的短輸入;如果您這樣做,請在註冊和登入時一致執行。

另一個陷阱是版本前綴。你會看到的 $2a$, $2y$, 和 $2b$ 在野外。 $2a$ 是原來的, $2y$ 是在某些實作中發現符號擴展錯誤後引入的 PHP 特定標籤,並且 $2b$ 是目前更正的 OpenBSD 版本。對於您想要的新雜湊值 $2b$,這就是這個工具產生的。所有三個對普通 ASCII 密碼進行相同的驗證;差異僅出現在 72 位元組邊界附近的特定非 ASCII 位元組。當您將令牌貼上到也檢查結構化憑證的工具中時,例如 JWT解碼器(請記住,bcrypt 雜湊不是您解碼以讀取有效負載的令牌;而是一個令牌。這是一個單向摘要,沒有什麼可透露的。

bcrypt 產生器適合實際工作流程的位置

就其本身而言,哈希值只是故事的一半,因此混合器與我保持開啟的其他憑證工具並存。當我播種測試資料庫或設定模擬帳戶時,我會使用以下方式自行產生密碼 密碼產生器,檢查它是否清除了合理的強度條 密碼強度檢查器,然後才將其運行通過 bcrypt 產生器 要獲得儲存的雜湊值。這個順序很重要:cost-12 bcrypt 雜湊後面的強隨機密碼確實很難破解,而同一雜湊後面的弱密碼仍然會受到字典攻擊,因為攻擊者只需猜測少數可能的候選者而不是整個密鑰空間。成本因素會為你贏得時間;密碼熵就是花費的時間。

驗證模式在偵錯過程中佔有一席之地。當登入在暫存中神秘失敗時,隔離問題的最快方法是貼上儲存的雜湊值和您認為正確的密碼,看看它們是否匹配。匹配意味著錯誤位於上游,密碼如何到達檢查;不匹配意味著儲存的雜湊值是用不同的密碼或損壞的編碼編寫的。任一答案都可以讓您免於猜測,並且由於整個事情都在本地運行,因此您可以使用從資料庫中提取的真實雜湊值來完成此操作,而無需該雜湊值離開您的電腦。網站上的每個工具背後都有相同的客戶端原則,對於任何涉及憑證的內容來說,這都不是好事,而是要求。

常見問題

在這個 bcrypt 產生器中雜湊真正的密碼安全嗎?

是的,因為雜湊完全發生在您的瀏覽器中,並且沒有任何內容發送到任何地方。您可以在開發人員工具的「網路」標籤中確認這一點:產生雜湊不會發出任何請求。也就是說,瀏覽器標籤不是密碼管理器,因此請避免將生產帳戶的即時憑證貼上到您未建立的任何網頁中,並在完成後關閉該標籤。

為什麼相同的密碼每次都會產生不同的 bcrypt 雜湊值?

因為 bcrypt 為每個雜湊產生一個新的隨機鹽並將其混合到結果中。這是一個功能:選擇相同密碼的兩個使用者仍然會獲得不同的儲存雜湊值,因此攻擊者無法發現共享密碼或重複使用預先計算的表。驗證仍然有效,因為鹽儲存在雜湊字串本身內。

bcrypt 應該使用什麼成本因素?

使用您的登入流程可以承受的最高成本,而不會出現煩人的延遲,對於大多數2020 年代的伺服器來說,延遲成本為10 到12。OWASP 建議在您的生產硬體上單次哈希應該需要大約四分之一秒的時間。因為每一步都會使工作量加倍,因此在自己的伺服器上進行測量而不是複製數字,並且隨著硬體加速,每隔幾年就會提高成本。

bcrypt 哈希值可以反轉回密碼嗎?

No。 Bcrypt 是一個單向函數,因此沒有數學方法可以將雜湊值變回原始密碼。唯一的攻擊是猜測:攻擊者以相同的鹽和成本對候選密碼進行雜湊處理並檢查匹配。這就是為什麼成本因素很重要,因為它決定了每個猜測的成本有多高,以及為什麼強大的唯一密碼加上高昂的成本使得猜測不切實際。

到 2026 年 bcrypt 仍然安全嗎?還是我應該切換到 Argon2?

Bcrypt 仍然被認為是密碼儲存的安全性,並且仍然是 OWASP 密碼儲存備忘單中的推薦選項。 Argon2id 是 2015 年密碼雜湊競賽的獲勝者,對於控制運行時的新系統來說是首選,因為它還可以抵抗 GPU 和專用硬體攻擊。 Bcrypt 是一個不錯的選擇,特別是當您的框架將其作為預設值提供時;真正的錯誤是使用快速通用雜湊而不是任何密碼雜湊函數。

bcrypt 中的 72 位元組限制是多少?

Bcrypt 只讀取 UTF-8 編碼密碼的前 72 個字節,因此超出該字節的任何字元都會被忽略。對於普通密碼,這並不重要,但可以截斷很長的密碼,這就是為什麼某些系統在 bcrypt 之前使用 SHA-256 預混雜密碼。每當您的輸入超過 72 位元組時,此工具都會向您發出警告,因此截斷絕非意外。

$2a$、$2b$ 和 $2y$ 前綴是什麼意思?

它們是 bcrypt 輸出格式的版本標籤。 $2a$ 是原始版本,$2y$ 是針對符號擴展錯誤的 PHP 特定修復,$2b$ 是目前更正的 OpenBSD 版本。對於新哈希,$2b$ 是正確的,這就是該工具產生的。所有三個都相同地驗證 ASCII 密碼;差異僅出現在 72 位元組邊界處的某些非 ASCII 位元組。

bcrypt 和加密一樣嗎?

不。加密可以用金鑰逆轉,因此加密資料可以解密回原始資料。 Bcrypt 雜湊是單向的,故意放慢速度,並且僅用於驗證:您永遠不需要恢復密碼,只需確認有人輸入了正確的密碼。使用加密而不是雜湊來儲存密碼是一種反模式,因為無論誰持有金鑰都可以恢復每個密碼。

Comments

0 comments

0/2000 characters

No comments yet. Be the first to share your thoughts!