bcrypt.CompareHashAndPassword报错“invalid hash”主因是哈希值为空、被截断(字段长度不足60)、含前后空格或前缀不支持(如$2y$),而非密码错误;调用GenerateFromPassword时须显式设cost=12、校验4–31范围、传[]byte明文并前置非空校验。
直接存 bcrypt 哈希到数据库没问题,但错在没控制
、没校验空密码、没处理哈希截断——这三个点踩中任意一个,
就会准时报错。
为什么 bcrypt.CompareHashAndPassword 总报 invalid hash
它不是在说“密码错了”,而是在拒绝解析你传入的哈希字符串。常见原因:
是空字符串或
(比如数据库查不到用户,
是零值)
字段长度不够:bcrypt 哈希固定 60 字节,但数据库列定义为
或更短,入库时被截断
前后有空格:
必须在比对前做,不能只靠前端传干净数据
存了 $2y$ 前缀的哈希(PHP 老系统迁移过来的),而 Go 的
不支持
调试时先打长度:
,不是 60 就立刻查源头。
如何安全调用 bcrypt.GenerateFromPassword
别用默认
(=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数组安全、编译
下载
新项目统一设
:实测在主流云服务器上单次耗时约 80–120ms,QPS 可撑 50+
从配置读取
值后,必须校验范围:
,否则
直接 panic 报
永远传原始字节:
,别提前
——空格可能是用户有意设置的密码一部分
注册前强制非空校验:
数据库字段与查询逻辑怎么配才不出错
哈希不是普通字符串,字段和查询都得按它的脾气来:
存哈希的字段类型必须是
或
(PostgreSQL 推荐后者),别用
或带长度限制的
中确保
结构体的
字段加了
,且没被误标为
导致忽略写入
登录查询必须检查错误:
,若
,直接返回失败,不进比对流程
比对前加空值防护:
,避免把空字符串喂给
导致 panic
迁移老数据或换算法时最易忽略的点
安全升级不是改一行代码的事:
从 PHP 迁移 $2y$ 哈希?别硬改源码,用正则提取
,拼成
再验
想切到 Argon2?bcrypt 哈希无法自动转,必须走双写过渡:新注册用 Argon2,旧用户登录成功后重哈希再覆盖
升级
值?用
检查已有哈希强度,只对
所有错误分支必须统一返回
,绝不暴露“用户不存在”或“密码错误”细节
真正麻烦的从来不是生成哈希那一行代码,而是哈希从内存进数据库、再从数据库拿出来比对的整条链路上,任何一环漏掉空值判断、长度校验或编码清理,都会让
在某个凌晨三点突然开始报错。
costhashedPassword is not the hash of the given passwordhashedPasswordniluser.PasswordVARCHAR(50)strings.TrimSpace()golang.org/x/crypto/bcryptfmt.Println(len(hashedPassword))bcrypt.DefaultCostcost = 12costif cost 31GenerateFromPasswordinvalid cost[]byte(password)strings.TrimSpaceif len(strings.TrimSpace(password)) ,避免静默哈希空密码VARCHAR(60)TEXTCHARVARCHARGORMUserPasswordgorm:"column:password"json:"-"err := i.DB.Where("email = ?", email).First(&user).Errorerr != nilif len(user.Password) == 0CompareHashAndPassword^\$2y\$(\d+)\$([A-Za-z0-9+/]{22})$2b$${cost}$${salt}costbcrypt.Cost(hashed)cost 的记录触发重哈希"invalid credentials"CompareHashAndPassword