crypto/aes 包仅提供底层AES分组密码原语,不封装加密模式或填充逻辑,使用CBC需手动处理随机IV和PKCS7填充,GCM需校验nonce与认证标签,密钥必须用PBKDF2等KDF派生而非直接哈希。

crypto/aes 包实现 AES 加密解密必须手动处理 IV 和填充
Go 标准库的 crypto/aes 只提供底层分组密码原语,不封装模式(如 CBC、GCM)或填充逻辑。直接调用 aes.NewCipher 得到的是一个纯块加密器,无法直接加密任意长度明文。
常见错误是忽略 IV(初始化向量)随机性或复用同一 IV,导致 CBC 模式下相同明文生成相同密文,严重削弱安全性。
- 使用 CBC 模式时,IV 必须每次加密都随机生成(
crypto/rand.Read),且随密文一起传输(通常前置) - Pkcs7 填充需手动实现:明文长度不足块大小(16 字节)时,在末尾补足差值个字节,每个字节值等于补的字节数
- 解密时先截出 IV,再用相同密钥+IV 解密,最后手动去除填充;若填充格式非法,应返回错误而非静默忽略
crypto/cipher.BlockMode 接口是连接 cipher 与 mode 的关键桥梁
crypto/cipher.BlockMode 是一个接口,由 cipher.NewCBCEncrypter、cipher.NewCBCDecrypter 等函数返回。它把底层 Block(如 AES 密钥调度结果)和模式逻辑(如异或上一个密文块)粘合起来,但本身不处理 IV 或填充。
容易混淆的是:这些函数接收的 IV 是 []byte,长度必须严格等于块大小(AES 为 16),且不能为 nil —— 即使你传入全零切片,也得显式分配 16 字节。
立即学习“go语言免费学习笔记(深入)”;
请注意以下说明:1、本程序允许任何人免费使用。2、本程序采用PHP+MYSQL架构编写。并且经过ZEND加密,所以运行环境需要有ZEND引擎支持。3、需要售后服务的,请与本作者联系,联系方式见下方。4、本程序还可以与您的网站想整合,可以实现用户在线服务功能,可以让客户管理自己的信息,可以查询自己的订单状况。以及返点信息等相关客户利益的信息。这个功能可提高客户的向心度。安装方法:1、解压本系统,放在
- 加密前确保明文长度是块大小整数倍(通过填充);否则
mode.CryptBlocks会 panic - 解密后得到的是带填充的原始字节,需独立验证并裁剪,
cipher包不提供自动去填工具 - 不要把同一个
BlockMode实例重复用于多次加密——它内部可能缓存状态,应每次新建
crypto/aes/gcm 比 CBC 更安全,但必须校验认证标签
crypto/cipher.NewGCM 返回的 AEAD 实现(如 AES-GCM)同时提供加密与完整性保护,无需手动填充,但引入了 nonce(非重复数)和认证标签(tag)概念。常见疏漏是忽略 tag 验证或重用 nonce。
nonce 长度由具体 AEAD 决定(AES-GCM 要求 12 字节),且绝不可重复使用同一密钥下的相同 nonce,否则密钥可能被恢复。
- 加密输出 = 密文 + 认证标签(默认 16 字节),解密时必须将最后 16 字节作为 tag 分离出来
- 调用
aead.Open时若 tag 不匹配,函数返回cipher.AEADDecryptError,不能忽略该错误继续使用解密结果 - nonce 应随密文存储/传输,但无需保密;推荐用
crypto/rand.Read生成,而非时间戳或计数器(除非严格保证唯一)
crypto/md5 和 crypto/sha256 不是加密算法,别误当密钥派生用
新手常把 crypto/md5.Sum 或 sha256.Sum256 当作“加密”来混淆数据,但它们是单向哈希,不可逆,也不适合直接当对称密钥用——长度固定、无密钥参与、易受彩虹表攻击。
若需从密码生成密钥(如用户口令 → AES 密钥),必须用专门的密钥派生函数,例如 golang.org/x/crypto/pbkdf2 或 scrypt,并设置足够迭代次数(PBKDF2 建议 ≥ 100,000)。









