Golang bcrypt
1. 概述
bcrypt
是一种安全的密码哈希算法,适用于存储用户密码,防止明文泄露。Golang 提供 golang.org/x/crypto/bcrypt
包来简化 bcrypt
的使用。
2. 安装
bcrypt
属于 Go 的扩展库,需要手动安装:
go get golang.org/x/crypto/bcrypt
3. 基本用法
3.1 生成哈希密码
package main
import (
"fmt"
"golang.org/x/crypto/bcrypt"
)
func main() {
password := "my_secure_password"
// 生成 bcrypt 哈希
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
fmt.Println("Error generating hash:", err)
return
}
fmt.Println("Hashed Password:", string(hashedPassword))
}
说明
bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
生成哈希密码。bcrypt.DefaultCost
是默认的计算成本(10
),可以调整为bcrypt.MinCost
(较快)或bcrypt.MaxCost
(更安全但更慢)。- 生成的哈希密码会自动包含
bcrypt
版本、成本因子和盐值。
3.2 校验密码
package main
import (
"fmt"
"golang.org/x/crypto/bcrypt"
)
func main() {
password := "my_secure_password"
hashedPassword := "$2a$10$P8HU5POQ9mC9dp5BqGkgYOdxz9b7zRbhq2bEn5B2c5rYrXsEoaQve" // 之前存储的哈希
// 验证密码
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
if err != nil {
fmt.Println("Password incorrect")
} else {
fmt.Println("Password correct")
}
}
说明
bcrypt.CompareHashAndPassword(hashedPassword, password)
验证密码是否匹配哈希值。- 如果密码匹配,返回
nil
,否则返回error
。
3.3 修改密码
要修改密码,直接生成新哈希并存储:
newPassword := "new_secure_password"
newHashedPassword, _ := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
fmt.Println("Updated Hashed Password:", string(newHashedPassword))
3.4 确定哈希是否需要更新
如果哈希密码的成本过低,可以使用 bcrypt.Cost()
确定是否需要更新:
cost, err := bcrypt.Cost([]byte(hashedPassword))
if err == nil && cost < bcrypt.DefaultCost {
fmt.Println("Password hash is outdated, consider updating")
}
监测哈希成本并升级
如果 bcrypt.Cost
返回的值小于当前推荐值(如 12
),则需要重新哈希密码:
const recommendedCost = 12
func upgradePasswordHash(storedHash string, password string) string {
cost, err := bcrypt.Cost([]byte(storedHash))
if err != nil {
fmt.Println("Error getting cost:", err)
return storedHash
}
// 如果成本因子过低,则重新生成哈希
if cost < recommendedCost {
newHash, err := bcrypt.GenerateFromPassword([]byte(password), recommendedCost)
if err != nil {
fmt.Println("Error upgrading hash:", err)
return storedHash
}
fmt.Println("Password hash upgraded.")
return string(newHash)
}
return storedHash
}
4. 适用场景
场景 | 说明 |
---|---|
用户密码存储 | 安全存储用户密码,防止明文泄露 |
密码验证 | 在用户登录时进行哈希匹配 |
密码更新 | 检测哈希是否过时,并重新加密 |
防止暴力破解 | bcrypt 计算开销高,能有效阻止暴力攻击 |
5. 总结
bcrypt.GenerateFromPassword()
生成哈希密码。bcrypt.CompareHashAndPassword()
验证密码。bcrypt.Cost()
检查哈希成本,确定是否需要升级。
Linux
/etc/shadow
存储的是加密后的密码哈希,格式如下:$<加密算法>$<成本因子或迭代次数>$<salt+hash>
常见的加密算法:
$1$
→ MD5$2a$
/$2b$
/$2y$
→ bcrypt$5$
→ SHA-256$6$
→ SHA-512示例(bcrypt):
$2y$10$XGnVZqM9JpWcPKCqGRBBtuNA7E6x2ZK.7JsZh9y1X1Ij0wY2brJve
$2y$
→ 使用 bcrypt 加密10
→ 计算成本(cost factor)XGnVZqM9JpWcPKCqGRBBtu
→ 盐(salt)NA7E6x2ZK.7JsZh9y1X1Ij0wY2brJve
→ 哈希后的密码