go标准库未提供aes-cfb的直接封装函数,需用cipher.newstream配合aes.block手动构建;iv必须16字节且每次唯一,加解密须共用同一block和完全相同的iv,xorkeystream要求dst与src底层数组分离,cfb-128不兼容cfb-8。

AES-CFB 在 Go 里没有现成的 crypto/aes 封装函数
Go 标准库不提供像 aes.NewCFBEncrypter 这样的直接封装,crypto/cipher 只暴露了底层的 cipher.Stream 接口,CFB 模式得自己用 cipher.NewStream 搭配 block 构建。这不是遗漏,是设计取舍:CFB 属于流模式(stream cipher),标准库统一交由 NewStream 管理,避免为每种模式重复造轮子。
常见错误是翻文档时只搜 “AES CFB Go”,然后卡在找不到 NewCFBEncrypter —— 它真不存在。你得手动传入 block 和初始向量(IV)来初始化流。
-
block必须来自aes.NewCipher(key),不能是随便一个 []byte - IV 长度必须等于 AES 块大小(16 字节),少一字节都会 panic:"
crypto/cipher: invalid buffer size for stream cipher" - CFB 模式下 IV 不需要保密,但每次加密必须唯一;重用 IV 会导致密文可预测,等同于裸奔
CFB 加密解密必须用同一个 block 实例 + 相同 IV 长度
CFB 是自同步流密码,加解密共享同一套状态机。Go 的 cipher.Stream 实现里,XORKeyStream(dst, src) 是原地异或操作,加解密逻辑完全对称——只要输入相同,就能还原。但前提是:加密和解密用的 block 密钥必须一致,IV 必须完全一样(字节级相等),且长度严格为 16。
典型翻车点:解密时重新 new 一个 aes.Block,但 key 或 IV 有毫秒级时间差导致的填充/截断(比如用 time.Now().UnixNano() 当 IV 又没保存),结果解出来全是乱码,错误信息不会报错,只会静默错乱。
立即学习“go语言免费学习笔记(深入)”;
- IV 应该随密文一起传输(比如 prepended),不要硬编码或从时间生成后丢弃
- 加密和解密代码里,
block要么共用一个变量,要么确保两次aes.NewCipher(key)的key是同一份[]byte(注意切片底层数组别被改) - CFB 不需要 padding,所以别调用
pkcs7或其他填充函数,否则解密会多出垃圾字节
cipher.Stream 的 XORKeyStream 是原地操作,别误传 dst 和 src 为同一 slice
XORKeyStream(dst, src) 会把 src 和密钥流异或后写进 dst。如果 dst == src(比如都传 data),行为未定义:可能部分字节被提前覆盖,导致后续异或错位。Go 1.20+ 会在 debug 模式下 panic:"cipher: invalid buffer overlap",但 release 模式下就静默崩坏。
正确做法永远保证 dst 和 src 是两个独立底层数组。哪怕只是临时 copy 一次,也比赌运气强。
- 加密:用
make([]byte, len(plaintext))当dst,plaintext当src - 解密:同理,
make([]byte, len(ciphertext))当dst,ciphertext当src - 别图省事写
stream.XORKeyStream(buf, buf),哪怕 buf 是局部变量也不行
CFB 模式在 Go 中的实际性能和兼容性边界
CFB 在 Go 里跑得不慢,但比 GCM 差一截:它无法并行,纯串行异或,吞吐受限于 CPU 单核。如果你要加密大文件或高并发小包,CFB 不是首选;但对小数据、低延迟场景(比如配置项加密、token 加壳),它足够轻量。
兼容性上要注意:Go 的 CFB 实现严格遵循 NIST SP 800-38A,但和其他语言(如 Python 的 Crypto.Cipher.AES)对接时,常因 IV 处理方式不同翻车。Python 默认用 mode=CFB 且 segment_size=8(即 CFB-8),而 Go 的 NewStream 固定是 CFB-128(全块反馈)。两者不互通。
- 跨语言对接前,务必确认对方用的是 CFB-128(不是 CFB-8/CFB-1),否则密文永远对不上
- Go 自己加密的密文,用 OpenSSL 解密要加
-cfb128参数,写成-cfb默认是 CFB-8,会失败 - CFB 不带认证,没法防篡改;如果业务需要完整性校验,得额外套一层 HMAC,或者直接换 GCM
CFB 最容易被忽略的其实是 IV 的生命周期管理——它不像 GCM 那样把 nonce 当参数透传,而是作为流初始化的一部分混在逻辑里,一不留神就复用或丢弃了。










