必须用scrypt.Key派生密钥而非直接使用用户密码,因原始密码熵低易被暴力破解;N设32768(交互场景)或1048576(文件加密),r固定为8,p设1,salt每次随机生成且≥32字节。

直接用用户密码当 AES 密钥是错的,scrypt.Key 必须介入——否则暴力破解几小时就能拿下。
scrypt.Key 参数怎么设才不翻车
Go 的 golang.org/x/crypto/scrypt 不提供默认参数,全靠你填。填错一个,密钥就错位,且不报错,只在解密时吐乱码。
-
N(CPU/内存成本):交互场景用32768(约 10MB 内存),文件加密可提至1048576(约 1GB),但别盲目堆高——实测超过2097152在低配 ARM 设备上会 OOM -
r(块大小):固定用8,这是绝大多数安全库的兼容基线;改它会导致跨语言无法互通 -
p(并行度):生产环境一律设为1;设成 >1 时,若目标机器 CPU 核数不足,scrypt.Key会静默降级,结果不可预测 -
salt:必须每次加密都调用crypto/rand.Read新生成,长度至少32字节;复用 salt = 等于把不同密码映射到同一密钥空间
为什么不能用 sha256.Sum256 替代 scrypt.Key
有人图省事写 sha256.Sum256([]byte(pw)).Sum(nil)[:32] 当密钥,这等于把门锁换成纸糊的。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- SHA256 是纯计算型哈希,GPU 每秒能跑上亿次,弱口令几秒撞穿
-
scrypt的防御核心是内存带宽瓶颈,攻击者得配大内存卡,成本指数级上升 - 标准库没
scrypt,但golang.org/x/crypto/scrypt是 Go 官方维护的子模块,和crypto/aes同等级别可信
密钥派生后怎么跟 AES-GCM 配合用
派生出的密钥只是起点,后续流程断一环,整个加密就失效。
立即学习“go语言免费学习笔记(深入)”;
- 输出密钥长度必须严格匹配算法要求:
AES-256-GCM要32字节,传16或24会 panic -
salt和nonce(IV)必须分开存储、分开生成:salt 用crypto/rand.Read,nonce 也必须用crypto/rand.Read(别复用 salt!) - 文件头结构要固化:比如前
32字节 salt → 接12字节 nonce → 后接密文;解密端必须按此偏移读,错 1 字节就解出垃圾 - 别漏校验:GCM 自带认证标签(tag),但 tag 必须和密文一起存,且解密时传给
cipher.AEAD.Open,否则失去完整性保护
最容易被跳过的不是算法本身,而是 salt/nonce/tag 三者的字节偏移定义——它不报错,只让密钥永远对不上。

















