跳转到主内容
极星编程网:以代码为星,赴技术山海!

Go语言bcrypt密码哈希_Golang安全存储用户密码方案

bcrypt.CompareHashAndPassword报错“invalid hash”主因是哈希值为空、被截断(字段长度不足60)、含前后空格或前缀不支持(如$2y$),而非密码错误;调用GenerateFromPassword时须显式设cost=12、校验4–31范围、传[]byte明文并前置非空校验。 直接存 bcrypt 哈希到数据库没问题,但错在没控制
cost
、没校验空密码、没处理哈希截断——这三个点踩中任意一个,
hashedPassword is not the hash of the given password
就会准时报错。 为什么 bcrypt.CompareHashAndPassword 总报 invalid hash 它不是在说“密码错了”,而是在拒绝解析你传入的哈希字符串。常见原因:
hashedPassword
是空字符串或
nil
(比如数据库查不到用户,
user.Password
是零值) 字段长度不够:bcrypt 哈希固定 60 字节,但数据库列定义为
VARCHAR(50)
或更短,入库时被截断 前后有空格:
strings.TrimSpace()
必须在比对前做,不能只靠前端传干净数据 存了 $2y$ 前缀的哈希(PHP 老系统迁移过来的),而 Go 的
golang.org/x/crypto/bcrypt
不支持 调试时先打长度:
fmt.Println(len(hashedPassword))
,不是 60 就立刻查源头。 如何安全调用 bcrypt.GenerateFromPassword 别用默认
bcrypt.DefaultCost
(=10),它在高并发下容易拖垮服务。生产环境应显式指定并管控成本因子: 立即学习 “ go语言免费学习笔记(深入) ”; go语言参考手册 中文CHM版 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译 下载 新项目统一设
cost = 12
:实测在主流云服务器上单次耗时约 80–120ms,QPS 可撑 50+ 从配置读取
cost
值后,必须校验范围:
if cost 31
,否则
GenerateFromPassword
直接 panic 报
invalid cost
永远传原始字节:
[]byte(password)
,别提前
strings.TrimSpace
——空格可能是用户有意设置的密码一部分 注册前强制非空校验:
if len(strings.TrimSpace(password)) ,避免静默哈希空密码
数据库字段与查询逻辑怎么配才不出错 哈希不是普通字符串,字段和查询都得按它的脾气来: 存哈希的字段类型必须是
VARCHAR(60)
或
TEXT
(PostgreSQL 推荐后者),别用
CHAR
或带长度限制的
VARCHAR
GORM
中确保
User
结构体的
Password
字段加了
gorm:"column:password"
,且没被误标为
json:"-"
导致忽略写入 登录查询必须检查错误:
err := i.DB.Where("email = ?", email).First(&user).Error
,若
err != nil
,直接返回失败,不进比对流程 比对前加空值防护:
if len(user.Password) == 0
,避免把空字符串喂给
CompareHashAndPassword
导致 panic 迁移老数据或换算法时最易忽略的点 安全升级不是改一行代码的事: 从 PHP 迁移 $2y$ 哈希?别硬改源码,用正则提取
^\$2y\$(\d+)\$([A-Za-z0-9+/]{22})
,拼成
$2b$${cost}$${salt}
再验 想切到 Argon2?bcrypt 哈希无法自动转,必须走双写过渡:新注册用 Argon2,旧用户登录成功后重哈希再覆盖 升级
cost
值?用
bcrypt.Cost(hashed)
检查已有哈希强度,只对
cost 的记录触发重哈希
所有错误分支必须统一返回
"invalid credentials"
,绝不暴露“用户不存在”或“密码错误”细节 真正麻烦的从来不是生成哈希那一行代码,而是哈希从内存进数据库、再从数据库拿出来比对的整条链路上,任何一环漏掉空值判断、长度校验或编码清理,都会让
CompareHashAndPassword
在某个凌晨三点突然开始报错。

相关文章