Bcrypt 簡介與加密和驗證示例【加密知多少系列_8】
〇、簡介
Bcrypt 是一種基于 Blowfish 加密算法的單向哈希函數,專為密碼存儲設計。它通過隨機鹽值(salt)和可調節的工作因子(cost factor)實現高安全性,是目前主流的密碼哈希算法之一。
核心原理:
- 隨機鹽值(Salt):每次加密時生成一個隨機鹽值(16 字節),與密碼混合后生成哈希值。確保相同密碼生成不同哈希值,防止彩虹表攻擊(Rainbow Table Attack)。
- 可調節的工作因子(Cost Factor):通過調整工作因子(log2:迭代次數),控制哈希計算的復雜度。范圍通常為 4~31(默認 10),值越大,計算時間越長,安全性越高。計算公式:迭代次數 = 2^cost(例如 cost=12 表示 4096 次迭代)。增加了暴力破解的時間成本,適應硬件性能提升。
- 基于 Blowfish 的密鑰擴展:大概流程,首先將密碼和鹽值組合,生成 EksBlowfish 密鑰(Expensive Key Schedule)。對固定字符串 "OrpheanBeholderScryDoubt" 進行多次 Blowfish 加密(根據工作因子決定迭代次數)。最終生成哈希值(60 字符的固定格式字符串)。
工作因子配置和計算耗時的大概規律:(注:基于博主當前機器的性能,僅供參考?。?/em>
| workFactor | 計算用時 |
| 8 | 16ms |
| 10(默認值,推薦) | 55ms |
| 12 | 210ms |
| 14 | 840ms |
| 16 | 3000ms+ |
// 密文的格式:
$2b$<cost>$<salt><hash>
// 示例:
$2b$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
// 各個部分的含義:
// $2b$:版本標識(2b 表示當前標準版本)。
// 10:工作因子(2^10 = 1024 次迭代)。
// N9qo8uLOickgx2ZMRZoMye:鹽值(22 字符,Base64 編碼)。
// IjZAgcfl7p92ldGxad68LJZdL17lhWy:哈希結果(31 字符)。
安全性:
抗彩虹表攻擊。每次加密使用隨機鹽值,相同密碼生成不同哈希值。彩虹表(預計算的哈希值表)無法直接匹配,需逐個嘗試破解。
抗暴力破解。工作因子控制計算時間(默認約 0.3 秒/次)。即使使用 GPU 并行計算,暴力破解成本極高(例如:cost=12 時,破解百萬級密碼需數年)。
自適應性。隨著硬件性能提升,可動態增加工作因子(如從 10 調整為 12),保持安全性。
與傳統哈希算法的對比:
| 特性 | Bcrypt | MD5/SHA 系列 |
|---|---|---|
| 抗彩虹表攻擊 | 強(通過鹽值和多次迭代) | 弱(容易受彩虹表攻擊) |
| 計算速度 | 慢(故意設計為“慢哈?!保?/td> | 快(適合文件校驗,但不適合密碼) |
| 工作因子 | 支持(可調) | 不支持 |
| 不可逆性 | 是(單向哈希) | 是(單向哈希) |
| 適用場景 | 密碼存儲 | 文件校驗、數字簽名(不推薦密碼) |
主要應用場景:
- 用戶密碼存儲:注冊和登錄時加密密碼,防止數據庫泄露后密碼被竊取。
- 企業級安全框架:Spring Security 推薦使用 BCryptPasswordEncoder,默認支持 Bcrypt。
- 數據保護:對敏感信息(如 API 密鑰)進行哈希處理,確保即使數據泄露也無法直接獲取明文。
一、C# 語言實現
先安裝依賴:Install-Package BCrypt.Net-Next。

具體加密和驗證實現:
using BCrypt.Net;
try
{
string password = "MySecurePassword123";
int workFactor = 16; // 默認值 10,取值范圍 4~31
// 加密
string hashedPassword = BCrypt.Net.BCrypt.EnhancedHashPassword(password, workFactor);
Console.WriteLine("Hashed Password:" + hashedPassword);
// $2a$10$n3WUdgGrTSVEZ1L3pTxkweeHXqUaWEXwvBI.gOnkTO17eL/ZqhBaG
// 驗證
bool isMatch = BCrypt.Net.BCrypt.EnhancedVerify(password, hashedPassword);
Console.WriteLine("Password Match:" + (isMatch ? "匹配" : "不匹配"));
}
catch (Exception ex)
{
Console.WriteLine("驗證失敗: " + ex.Message);
}
//Hashed Password:$2a$12$h8EnoQF6QYZDtbrCSGuDxeKjMt.Y0dcnWjFrz4sgEyhXlt.5VQs7G
//Password Match:匹配
二、js 語言實現
引用第三方庫 bcryptjs 實現加密和驗證。安裝命令:
npm install bcryptjs
加密和驗證的簡單示例代碼:
const bcrypt = require('bcryptjs');
try {
// 要加密的密碼
const password = 'MySecurePassword123';
// 工作因子(cost factor):控制哈希復雜度,推薦值 10
const saltRounds = 10;
// 【加密】生成鹽并哈希密碼(異步)
const hashedPassword = await bcrypt.hash(password, saltRounds)
console.log('Hashed Password:', hashedPassword);
// 【解密】
const bcrypt = require('bcryptjs');
// 用戶輸入的密碼
const inputPassword = 'MySecurePassword123';
// 數據庫中存儲的哈希值
const storedHashedPassword = '$2a$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy';
// 驗證密碼是否匹配
const isMatch = await bcrypt.compare(inputPassword, storedHashedPassword);
}
catch (error) {
console.error('Error:', error);
}
三、go 語言實現
在 Go 語言中使用 Bcrypt 進行密碼哈希和驗證,通常依賴官方推薦的第三方庫 golang.org/x/crypto/bcrypt。該庫提供了安全、高效的 Bcrypt 實現,適合用于密碼存儲和驗證場景。
// 安裝
go get golang.org/x/crypto/bcrypt
加密和驗證簡單示例:
package main
import (
"fmt"
"golang.org/x/crypto/bcrypt"
)
func main() {
// 明文密碼
password := "MySecurePassword123"
// 【生成】哈希密碼(使用默認工作因子)
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
// hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), 12) // 自定義工作因子
if err != nil {
panic("生成哈希失敗: " + err.Error())
}
fmt.Println("Hashed Password:", string(hashedPassword))
// 【驗證】密碼是否匹配
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
if err != nil {
fmt.Println("密碼不匹配:", err)
} else {
fmt.Println("密碼匹配")
}
}
本文來自博客園,作者:橙子家,歡迎微信掃碼關注博主【橙子家czzj】,有任何疑問歡迎溝通,共同成長!

浙公網安備 33010602011771號