Go语言实现AES-128-CFB8解密失败,求技术支持
Go语言AES-CFB8解密失败问题解决方法
问题核心:你的Python和C++代码采用的是AES-128-CFB8模式(每次加密/解密处理1字节),但Go标准库的cipher.NewCFBDecrypter实现的是CFB128(每次处理16字节的AES块),两者密钥流生成逻辑不一致,导致解密结果错误。
解决思路
Go标准库没有直接提供CFB8的实现,需要手动模拟CFB8的解密逻辑:基于AES块密码维护一个16字节的反馈寄存器,每次生成1字节密钥流与密文字节异或得到明文,再将密文字节(而非明文)反馈回寄存器,循环处理所有密文。
修正后的完整代码
package main import ( "crypto/aes" "crypto/cipher" "crypto/sha1" "encoding/base64" "fmt" "strings" ) // cfb8Decrypt 手动实现AES-CFB8解密 func cfb8Decrypt(block cipher.Block, iv []byte, ciphertext []byte) []byte { blockSize := block.BlockSize() if len(iv) != blockSize { panic("iv length must equal block size") } plaintext := make([]byte, len(ciphertext)) feedback := make([]byte, blockSize) copy(feedback, iv) for i := range ciphertext { // 生成密钥流块 keystream := make([]byte, blockSize) block.Encrypt(keystream, feedback) // 取密钥流第一个字节与密文异或得到明文 plaintext[i] = ciphertext[i] ^ keystream[0] // 更新反馈寄存器:移除首字节,追加当前密文字节 copy(feedback, feedback[1:]) feedback[blockSize-1] = ciphertext[i] } return plaintext } func main() { key := "bigsecretdon'ttellanyone" shaKey := sha1.Sum([]byte(key)) keySlice := shaKey[:16] // 取SHA1前16字节作为AES-128密钥 encpass := "e0,cxMarJhf8bGHe+Vko1uxdw==,9InGiLOqWB/OZsLGBqW4tlk=" // 拆分加密字符串 pieces := strings.Split(encpass, ",") if len(pieces) != 3 { panic("Invalid password string") } iv, err := base64.StdEncoding.DecodeString(pieces[1]) if err != nil { panic(err) } ciphertext, err := base64.StdEncoding.DecodeString(pieces[2]) if err != nil { panic(err) } // 创建AES块密码实例 block, err := aes.NewCipher(keySlice) if err != nil { panic(err) } // 执行CFB8解密 plaintext := cfb8Decrypt(block, iv, ciphertext) fmt.Printf("解密结果: %s\n", plaintext) }
关键细节说明
- 反馈规则:CFB模式解密时,反馈到下一轮的是密文字节,而非明文,这是保证与原有Python/C++实现兼容的核心。
- 密钥流生成:每次用当前反馈寄存器加密生成16字节密钥流,仅取第一个字节用于当前密文字节的解密。
- 寄存器移位:每处理一个字节,反馈寄存器左移1字节,末尾追加当前密文字节,确保下一轮反馈逻辑正确。
内容的提问来源于stack exchange,提问作者Michael Soulier
相关产品推荐
相关产品推荐

