不能直接裸调 aes.newcipher 和 cipher.newcbcencrypter,因密钥长度校验、iv 随机生成、pkcs7 填充及错误处理等细节易出错;必须封装构造器强制校验密钥、每次加密生成新 iv 并与密文绑定、内聚填充逻辑。

为什么不能直接用 aes.NewCipher 做全局加密工具
直接裸调 aes.NewCipher + cipher.NewCBCEncrypter 容易出错,不是因为不会写,而是因为密钥长度、IV 生成方式、填充逻辑、错误处理这些细节分散在各处,一改全崩。比如你忘了 PKCS7 填充,解密时就会 panic;或者把 IV 硬编码进代码,导致每次加密结果相同,完全失去安全性。
Encrypt 和 Decrypt 函数必须强制接收 []byte 类型的密钥
Go 的 aes.NewCipher 对密钥长度极其敏感:只接受 16/24/32 字节。传入字符串或长度不对的切片会直接 panic。常见错误是用 []byte("mykey") —— 长度只有 5,根本过不了校验。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
- 必须提前校验密钥长度,而不是依赖运行时报错
- 不建议自动截断或补零(如
key[:16]),这会削弱密钥熵值,应由调用方明确提供合规密钥 - 推荐封装成
func NewAES(key []byte) (*AES, error)构造器,在初始化时就做长度检查 - 密钥本身不应出现在源码里,应从环境变量或 KMS 加载后传入
IV 必须随密文一起存储,且每次加密都要新生成
CBC 模式下,IV 是加密安全的前提。复用 IV 相当于把 CBC 退化成 ECB,明文相同则密文相同,极易被模式分析攻击。但很多人图省事,用固定 IV 或时间戳拼接,这等于没加。
- 用
crypto/rand.Read生成 16 字节 IV,不要用math/rand - 加密输出格式建议为:
IV + ciphertext(前 16 字节是 IV,后面是密文) - 解密时先切出前 16 字节作为 IV,再用剩余部分解密
- 不要把 IV 存在单独字段或配置里 —— 它和密文是原子绑定的
填充和去填充逻辑必须内聚,不能暴露给业务层
PKCS7 填充看似简单,但边界情况很多:空明文、刚好整除块大小、解填充时 padding 值非法等。如果每个业务都自己写一遍 pkcs7Pad,很快就会出现不一致。
- 填充逻辑应封装在加密函数内部,业务只传原始明文
- 解填充必须校验 padding 值是否在 [1,16] 范围内,且末尾字节全部相等,否则返回 error
- 避免用
bytes.Repeat生成 padding,而应手动构造,防止潜在越界 - 如果业务需要支持非 PKCS7(比如 ZeroPadding),应通过选项参数控制,而非另起一套函数
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










