一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何使用 Go语言 对敏感数据执行 AES 混淆加密与解密

时间:2026-07-13 09:17:24 编辑:袖梨 来源:一聚教程网

密钥长度必须为16、24或32字节,否则aes.NewCipher直接panic;CBC需校验IV和PKCS#7填充;GCM严禁nonce重用且tag必须显式分离;ECB绝对禁用。

密钥长度不对直接 panic,别信“差不多”

aes.NewCipher 不会宽容——传入 15 或 17 字节的密钥,它立刻抛出 crypto/aes: invalid key size。Go 不做截断、不补零、不提示“建议用 16”,只认死理:len(key) 必须是 16、24 或 32。

  • 硬编码测试时,显式写满:比如 []byte("1234567890123456")(注意:无空格、无换行、无 BOM)
  • 从环境变量或配置读取时,别用 len(key) 检查字符串长度;要用 len([]byte(key)),否则含中文或 emoji 会误判
  • 生产环境推荐派生:用 sha256.Sum256([]byte(raw)).[0:32] 得到稳定 32 字节密钥,避免人为数错

CBC 模式下解密乱码?先看 IV 和填充是否对得上

CBC 解密失败几乎从不报错,只会输出乱码。问题大概率出在三处:IV 切片位置错、PKCS#7 填充没验、明文末尾被截断。

  • 密文开头必须是 16 字节 IV,解密时用 ciphertext[:aes.BlockSize()] 提取,剩余部分才是真实密文
  • 填充必须严格按 PKCS#7:若原长 mod 16 = 5,则补 11 个 x0b;若刚好整除,要额外补 16 个 x10
  • 解密后不能直接 orig[:len(orig)-pad],得先读末字节 n := orig[len(orig)-1],再验证最后 n 字节是否全等于 n,否则可能是篡改或 IV 错

GCM 模式不是“更简单”,而是更易踩 nonce 重用的坑

cipher.NewGCM 返回的 AEAD 接口确实省去填充和手动 IV 管理,但 nonce 重用后果比 CBC IV 复用严重得多:攻击者可直接恢复密钥。

  • nonce 长度固定为 12 字节(Go 默认),不是 16,也不是随便设
  • 必须用 crypto/rand.Read(nonce) 生成,且每次加密都新生成——别拼时间戳、别用计数器、别复用
  • 密文结构是 nonce + ciphertext + tag(tag 默认 16 字节),解密前必须把最后 16 字节切出来当 tag,传给 aead.Open
  • aead.Open 返回 cipher.AEADDecryptError 表示认证失败,此时绝不能忽略错误继续用解密结果

ECB 模式别用,哪怕只是“临时混淆”

ECB 看似最简:不用 IV、不用填充、block.Encrypt 直接循环调用。但它让相同明文块永远输出相同密文块,比如日志里反复出现的 "status:success" 会被识别为固定密文模式,等同于裸奔。

立即学习“go语言免费学习笔记(深入)”;

  • 即使只是混淆(非强加密),也请至少用 CBC + 随机 IV —— IV 明文附在密文前不增加风险,但彻底打破确定性
  • 别用 key[:16] 当 IV:这等于把密钥的一部分暴露给攻击者,且完全丧失随机性
  • 流式加密大文件时,CBC 仍需完整填充,GCM 更适合;但无论哪种,io.ReadFull(rand.Reader, iv)rand.Read(iv) 更安全,避免读不满
实际加解密逻辑里最脆弱的一环,往往不是算法本身,而是密钥/IV/tag 的边界切割动作——多一个字节、少一个字节、切错位置,都会让解密变成“看似成功”的乱码。动手前,先盯住那几行切片和长度校验。

热门栏目