bcrypt 雜湊無法「解密」:若要確認密碼是否正確,請使用驗證模式。所有計算都在你的瀏覽器中進行,密碼不會傳送到任何伺服器。
目前版本。由 OpenBSD、Node.js、Python、Go 與 Rust 產生。
成本每增加 1,計算時間就加倍。OWASP 建議至少為 10;理想值是伺服器能在約 250 毫秒內算完的最高值。
運作方式
bcrypt 是專為儲存密碼設計的雜湊函式。與幾微秒就能算完的 SHA-256 或 MD5 不同,bcrypt 刻意設計得很慢:如此一來,即使有人竊取了資料庫,以暴力破解嘗試密碼也得花上好幾年。
每個雜湊都包含驗證所需的全部資訊:演算法版本、成本與 128 位元的隨機鹽值。因此同一個密碼每次都會得到不同的雜湊,也不需要另外儲存鹽值。
成本是輪數以 2 為底的對數:成本 10 會計算 1024 輪,成本 12 則是 4096 輪。每增加 1,計算時間就加倍,因此不必更換演算法也能跟上硬體效能的提升。
範例
rasmuslerdorf$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1aPHP 手冊中 password_verify() 的範例:在驗證模式中將它與該密碼一起貼上,就會顯示相符。abc$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0ijBCrypt 中成本為 6 的測試向量。成本之後的前 22 個字元是鹽值,其餘 31 個字元是雜湊結果。使用情境
- 為管理員使用者的初始密碼產生雜湊,直接寫入資料庫。
- 使用者無法登入時,檢查密碼是否與儲存的雜湊相符。
- 為 Laravel、Spring、Django 或 Node.js 應用程式的 fixtures、seeds 或自動化測試產生測試用雜湊。
- 在伺服器上設定之前,測量每種成本的耗時,選擇合適的值。
- 為 Apache 的 .htpasswd 檔案建立項目,它接受前綴為 $2y$ 的 bcrypt 雜湊。
常見問題
bcrypt 雜湊可以解密嗎?
不行。bcrypt 是單向函式:無法從雜湊還原出密碼。唯一能做的是嘗試候選密碼,看看是否有相符的,而 bcrypt 正是要讓這個過程變慢。
$2a$、$2b$ 與 $2y$ 有什麼差別?
對一般密碼而言,三者的計算結果相同。$2a$ 是原始版本;$2y$ 是 PHP 在 2011 年引入的,用來將自家的雜湊與某個有缺陷的實作區分開來;$2b$ 是 OpenBSD 在 2014 年修正另一個與超過 255 個字元的密碼有關的缺陷時採用的。幾乎所有函式庫在驗證時都接受這三種版本。
應該使用多少成本?
OWASP 建議至少為 10。理想值是伺服器每次登入能在約 250 毫秒內算完的最高值。Spring Security 預設使用 10;Laravel 11 與 PHP 8.4 已將預設值提高到 12。
為什麼 bcrypt 會忽略超過 72 位元組的部分?
此演算法把密碼當作 Blowfish 的金鑰,而金鑰最多 72 位元組。超出的部分會在沒有任何提示的情況下被捨棄,因此前 72 位元組相同的兩個密碼會得到相同的雜湊。帶重音的字元或表情符號佔 2 到 4 個位元組,所以本工具計算的是位元組數而不是字元數。
bcrypt 和 Argon2 哪個比較好?
目前新系統建議使用 Argon2id,因為它不只慢,還會使用大量記憶體,提高 GPU 攻擊的成本。不過只要成本設定得當,bcrypt 依然安全,而且是 PHP、Laravel、Spring 與 Ruby on Rails 的預設演算法。
我的密碼會傳送到伺服器嗎?
不會。雜湊的產生與驗證都在你的瀏覽器中進行,密碼永遠不會離開你的裝置;分享工具的連結中也不會包含密碼。