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 字符的固定格式字符串)。

工作因子配置和计算耗时的大概规律:(注:基于博主当前机器的性能,仅供参考!)

|----------------|----------|
| 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 系列
抗彩虹表攻击 强(通过盐值和多次迭代) 弱(容易受彩虹表攻击)
计算速度 慢(故意设计为"慢哈希") 快(适合文件校验,但不适合密码)
工作因子 支持(可调) 不支持
不可逆性 是(单向哈希) 是(单向哈希)
适用场景 密码存储 文件校验、数字签名(不推荐密码)

主要应用场景:

  • **用户密码存储:**注册和登录时加密密码,防止数据库泄露后密码被窃取。
  • **企业级安全框架:**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("密码匹配")
    }
}
相关推荐
aircrushin10 分钟前
端到端AI决策架构如何重塑实时协作体验?
前端·javascript·后端
苦瓜小生18 分钟前
【黑马点评学习笔记 | 实战篇 】| 6-Redis消息队列
redis·笔记·后端
yhole1 小时前
springboot 修复 Spring Framework 特定条件下目录遍历漏洞(CVE-2024-38819)
spring boot·后端·spring
BingoGo1 小时前
Laravel 13 正式发布 使用 Laravel AI 无缝平滑升级
后端·php
l软件定制开发工作室1 小时前
Spring开发系列教程(34)——打包Spring Boot应用
java·spring boot·后端·spring·springboot
随风,奔跑1 小时前
Spring MVC
java·后端·spring
美团技术团队2 小时前
美团 BI 在指标平台和分析引擎上的探索和实践
后端
JimmtButler2 小时前
我用 Claude Code 给 Claude Code 做了一个 DevTools
后端·claude
Java水解2 小时前
Java 中实现多租户架构:数据隔离策略与实践指南
java·后端
Master_Azur2 小时前
Java面向对象之多态与重写
后端