bcrypt.generatefrompassword需传[]byte明文和cost(推荐bcrypt.defaultcost=12),明文超72字节会被静默截断,校验必须用bcrypt.comparehashandpassword防时序攻击,哈希值为ascii字符串($2a$/$2b$开头),存数据库用string(hashed)。

bcrypt.GenerateFromPassword 怎么用才不翻车
直接传明文和 cost 就能出哈希,但翻车点全在参数和类型上:GenerateFromPassword 第一个参数必须是 []byte,不是 string;第二个参数别硬写 10 或 15,优先用 bcrypt.DefaultCost(当前是 12),它平衡了安全与响应延迟。
- 明文超 72 字节会被静默截断——
"password123"和"password123xxxxxxxxxx..."哈希结果一样,务必在入参前做长度校验(比如限制 8–64 字符) - 别自己拼 salt、别用
sha256或md5加盐后比对——bcrypt内置随机 salt,每次调用生成的哈希都不同,这是防彩虹表的核心 - 哈希结果是 ASCII 字符串(以
$2a$、$2b$开头),存数据库时直接用string(hashed)转,别存[]byte二进制,否则读出来乱码或报错
为什么必须用 bcrypt.CompareHashAndPassword 校验
手写 == 或 bytes.Equal 会触发 timing attack(时序攻击):攻击者通过比对耗时差异反推密码字符。而 CompareHashAndPassword 是恒定时间比对,无论前几位是否匹配,执行时间都一致。
- 参数顺序不能反:第一个是数据库里存的哈希字符串转成的
[]byte,第二个才是用户提交的明文密码[]byte - 返回
nil表示匹配成功,其他错误(比如bcrypt.ErrMismatch)都算失败,别只判err != nil就完事——要明确处理不匹配场景 - 哈希前缀只支持
$2a$和$2b$,如果从旧系统迁移过来遇到$2y$,得先升级库或转换格式,否则直接 panic
cost 设成多少才合理
cost 不是越高越好,也不是默认最省事。2026 年主流服务端硬件下,cost=12(即 DefaultCost)是实测平衡点:注册耗时约 150–250ms,不影响用户体验;暴力破解成本足够高,且不会在登录高峰拖垮 CPU。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 设成
10:太低,现代 GPU 几秒就能跑千万次尝试 - 设成
14以上:单次哈希可能突破 1s,高并发登录接口容易超时或积压 - 别在开发环境用
cost=4测试——行为偏差大,上线后才发现性能崩了
常见错误现象和定位线索
哈希值长得一样?密码总校验失败?接口突然变慢?这些都不是玄学,基本都能对应到具体操作失误:
-
panic: hashedPassword is not the hash of a password:传给CompareHashAndPassword的第一个参数不是合法 bcrypt 哈希(比如被 base64 编码过、开头少了$2b$、或者字段从 JSON 直接 decode 出来没 trim 空格) - “同一个密码,两次注册存的哈希一模一样”:大概率用了自己生成的固定 salt,或者误把
md5(password+salt)当 bcrypt 用了 - “用户输对密码也登不上,但换个浏览器就成”:其实是 session 或 cookie 问题,不是 bcrypt 本身故障,别一上来就怀疑哈希逻辑
bcrypt 的哈希字符串本身自带 salt 和 cost 信息,解码时不需要额外字段;真正要盯紧的,是传进去的字节切片有没有被意外修改、截断或编码污染。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










