crypto包是工具集而非开箱即用的安全方案:sha-256不可直接存密码,须用pbkdf2/scrypt加盐迭代;aes应优先选gcm而非cbc;rsa需混合加密且严守长度限制;密钥和iv绝不可硬编码,须动态生成并安全管理。

crypto 包不是“开箱即用”的安全方案,而是工具集——直接调用 sha256.Sum256 或 aes.NewCipher 不等于实现了安全加密,关键在上下文、参数选择和组合方式。
为什么 crypto/sha256 不能直接存密码
SHA-256 是纯哈希,无盐、无迭代、无密钥,输入相同则输出绝对一致。攻击者用预计算的彩虹表或暴力穷举(如 "password123")能秒破。
- 正确做法是用
golang.org/x/crypto/pbkdf2或scrypt,至少 10 万轮迭代 + 随机 salt -
sha256.Sum256([]byte("pwd"))只适合校验文件完整性,绝不可用于密码哈希 - 若必须用 SHA 系列做认证,应搭配 HMAC:用
hmac.New(sha256.New, key),而非裸哈希
crypto/aes 选 GCM 还是 CBC?看是否需要认证
CBC 模式只保证机密性,不防篡改;GCM 是 AEAD(认证加密),一次调用同时产出密文 + 认证标签(tag)。网络传输、API 响应加密必须用 GCM 或 ChaCha20-Poly1305。
- GCM 要求 nonce 绝对唯一:每次加密用
crypto/rand.Read(nonce),不能复用、不能计数器递增(除非严格控制域) - CBC 必须配合 PKCS#7 填充,且需额外加 HMAC 校验,否则易受 padding oracle 攻击
-
cipher.NewGCM(block)返回的gcm.Seal()输出包含 nonce + ciphertext + tag,三者缺一不可
crypto/rsa 加密失败常见于填充和长度限制
RSA 不是“拿来就能加密任意长数据”的黑盒。2048 位密钥下,OAEP 填充最多加密约 190 字节;PKCS#1 v1.5 更少(约 214 字节),超长直接 panic。
- 永远不要用 RSA 直接加密用户输入:先用
rsa.EncryptOAEP加密一个随机 AES 密钥,再用该密钥加密实际数据(混合加密) - 私钥解密时,若传入的密文长度 ≠
privateKey.Size(),会返回"crypto/rsa: decryption error" - 公钥加密必须用
rsa.PublicKey类型,传入*rsa.PrivateKey会导致 panic:类型不匹配而非错误信息友好提示
硬编码密钥和固定 IV 是生产环境最高频的漏洞源头
代码里写 key := []byte("1234567890123456") 或 iv := make([]byte, 12) 看似能跑通,但等于把保险柜钥匙焊死在门把手上。
- 密钥应从 KMS(如 AWS KMS、HashiCorp Vault)拉取,或通过环境变量注入(确保进程启动前已 set,且不被 ps 显示)
- IV/nonce 必须每次加密都新生成,且与密文一起序列化传输(如 JSON 中存
"iv"和"ciphertext"字段) - 测试时用固定 IV 可以,但上线前必须删掉所有
iv := bytes.Repeat([]byte{0}, 12)类代码
Encrypt 函数,而是判断该不该用它、用在哪一层、谁负责生成/保管/轮换密钥、失败时如何不泄露侧信道信息——这些不会报错,但会让整个加密形同虚设。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











