
crypto/md5 和 crypto/sha256 为什么不能直接比较字符串?
因为 md5.Sum 和 sha256.Sum 是结构体,不是字符串;直接用 == 比较会得到 false,哪怕哈希值完全一样。
常见错误现象:if md5.Sum(data) == md5.Sum(other) { ... } 总是进不去分支。
- 正确做法是调用
.Sum(nil)得到[]byte,再用bytes.Equal()比较 - 或用
fmt.Sprintf("%x", sum)转成小写十六进制字符串(注意别漏掉%x,%X大写会导致不一致) - SHA-256 输出长度固定 32 字节,MD5 是 16 字节——如果做校验,长度本身就能快速排除错误输入
AES 加密时 crypto/aes.NewCipher 报 “invalid key size” 怎么办?
Go 的 aes.NewCipher 只接受 16、24 或 32 字节密钥,对应 AES-128 / AES-192 / AES-256。传入其他长度(比如 12 或 20)必然 panic。
使用场景:从配置读密钥字符串,但没做长度校验。
立即学习“go语言免费学习笔记(深入)”;
- 别直接用原始字符串当密钥,先用
sha256.Sum256([]byte(key)).Sum(nil)[:32]截取(AES-256) - CBC 模式必须配 IV(16 字节),且每次加密都要换;别复用 IV,否则相同明文会产生相同密文
- ECB 模式在
crypto/cipher里不提供——这是故意的,它不安全,别自己实现
RSA 私钥解密失败,提示 “crypto/rsa: decryption error”
这个错误几乎总是因为填充方式不匹配:加密时用了 rsa.EncryptPKCS1v15,解密却用了 rsa.DecryptOAEP,或者反之。
性能影响:OAEP 比 PKCS#1 v1.5 更安全,但计算稍重;短消息(
- 公钥加密 + 私钥解密场景下,加解密两端必须用同一填充函数
- 私钥长度要够:2048 位是底线,4096 更稳妥;用
ssh-keygen -t rsa -b 4096生成的私钥需用golang.org/x/crypto/ssh解析,标准库不支持 OpenSSH 格式 -
rsa.Decrypt返回的明文可能带前导零字节(尤其 PKCS#1 v1.5),别直接当 UTF-8 字符串打印,先bytes.TrimLeft(res, "\x00")
crypto/rand.Reader 和 math/rand 不要混用
crypto/rand.Reader 是密码学安全的真随机源,math/rand 是伪随机,种子一旦暴露,整个序列可预测。拿后者生成 AES 密钥或 RSA 私钥,等于把锁换成纸糊的。
容易踩的坑:本地测试时图省事用 math/rand 填充测试数据,上线后忘记替换。
- 生成密钥、IV、salt、nonce —— 全部走
crypto/rand.Read(buf) -
crypto/rand在 Windows 上依赖CryptGenRandom,Linux 用/dev/urandom,无需额外配置 - 别为了“快”缓存
crypto/rand.Reader结果——它本身已做缓冲,重复调用开销极小
哈希要防碰撞,AES 要管好 IV 和模式,RSA 要对齐填充和密钥长度,随机源绝不能凑合——这些点单独看简单,但组合起来,少一个就可能让整套加解密失效或被绕过。










