Go加密JavaScript解密遇异常,请求排查解密配置问题
Go AES-CFB加密与JS解密不兼容问题排查
问题场景
用Go实现AES-CFB加密功能后,在JavaScript端解密时出现两个问题:
- 解密返回的字符串仅125字符长
- 短文本有时无法解密
更换加密解密模式后问题仍未解决,需排查解密配置问题。
Go 加密代码
func Encrypt(text string) (string,error) { secretKey := "XM1IyN4ZOJfcbDH3Md7m7XmNGGjtXMJw" block, err := aes.NewCipher([]byte(secretKey)) if err != nil { log.Fatal(err) return "", err } plainText := []byte(text) iv := []byte("7061737323313233") cfb := cipher.NewCFBEncrypter(block, iv) cipherText := make([]byte, len(plainText)) cfb.XORKeyStream(cipherText, plainText) return base64.StdEncoding.EncodeToString(cipherText), nil }
原JavaScript解密代码
var key = CryptoJS.enc.Utf8.parse('XM1IyN4ZOJfcbDH3Md7m7XmNGGjtXMJw'); var iv = CryptoJS.enc.Utf8.parse('7061737323313233'); var encryptedData = "7sEPYaArhx0YGAqDzYHvhZFOCBvmbzAmZBCp7AwrRCiYPGlS9y+zA18qj9afqeEm00qvGBRkQA24MwK9jxStpkaS8VvGs78VyG1vt2CsEIagXFiokdj6AnuwrYt2kUp7Xex3qurYr3B4bl2jlPeA6kzB0XeG07vB5teblvvfkRgwQ3Mvph+soCPJ9byTqycdjqa4qpgWnvN3KpMWu7cmYvOITOXhv0K88SLvVKg4VRzpxJ3DtUmIF2fm8M6jQ1I6uIvNFVV3WV6pp8MDq31/xe0vFDujNBp/RYiYyB456pnj0gHPlvlVS6SblTZc11wsCU8GPClnlCyZkeIICKRKCEGyfh7tQLMRMRlcjmWDRdcMx9zFDRroNeHYeG1+b/H4TOgVQG1iqkM9O8/4TD1m2BvYe8ZH7248ceqZucFfSa0rigLZE1K1B/QnQGOfpxuTJjMkw7qdmnm4v6yYOBJPNZa1L5zo9L/RWpkSYzRcjus5wHzuyi8a"; var decrypted = CryptoJS.AES.decrypt(encryptedData, key, { keySize: 256 / 8, iv: iv, mode: CryptoJS.mode.CFB, padding: CryptoJS.pad.Pkcs7 }); var decryptedText = decrypted.toString(CryptoJS.enc.Utf8); console.log("Decrypted Text:", CryptoJS.enc.Utf8.stringify(decrypted));
问题原因
- CFB分段大小不匹配:
Go 的cipher.NewCFBEncrypter默认使用128位(16字节)分段大小(与AES块大小一致),而 CryptoJS 中的CryptoJS.mode.CFB默认是64位(8字节)分段大小,密钥流生成逻辑不一致,导致解密数据截断或乱码。 - 多余的Padding配置:
CFB属于流加密模式,不需要填充(Padding),但原JS代码中配置了padding: CryptoJS.pad.Pkcs7,会导致解密时额外进行填充校验,破坏原始数据。
修复后的JavaScript解密代码
var key = CryptoJS.enc.Utf8.parse('XM1IyN4ZOJfcbDH3Md7m7XmNGGjtXMJw'); var iv = CryptoJS.enc.Utf8.parse('7061737323313233'); var encryptedData = "7sEPYaArhx0YGAqDzYHvhZFOCBvmbzAmZBCp7AwrRCiYPGlS9y+zA18qj9afqeEm00qvGBRkQA24MwK9jxStpkaS8VvGs78VyG1vt2CsEIagXFiokdj6AnuwrYt2kUp7Xex3qurYr3B4bl2jlPeA6kzB0XeG07vB5teblvvfkRgwQ3Mvph+soCPJ9byTqycdjqa4qpgWnvN3KpMWu7cmYvOITOXhv0K88SLvVKg4VRzpxJ3DtUmIF2fm8M6jQ1I6uIvNFVV3WV6pp8MDq31/xe0vFDujNBp/RYiYyB456pnj0gHPlvlVS6SblTZc11wsCU8GPClnlCyZkeIICKRKCEGyfh7tQLMRMRlcjmWDRdcMx9zFDRroNeHYeG1+b/H4TOgVQG1iqkM9O8/4TD1m2BvYe8ZH7248ceqZucFfSa0rigLZE1K1B/QnQGOfpxuTJjMkw7qdmnm4v6yYOBJPNZa1L5zo9L/RWpkSYzRcjus5wHzuyi8a"; // 核心修改:使用CFB128匹配Go端的分段大小,移除padding配置 var decrypted = CryptoJS.AES.decrypt(encryptedData, key, { keySize: 256 / 8, iv: iv, mode: CryptoJS.mode.CFB128 }); var decryptedText = decrypted.toString(CryptoJS.enc.Utf8); console.log("Decrypted Text:", decryptedText);
额外说明
- Go端的IV和Key处理是正确的,与JS端的
Utf8.parse逻辑一致,无需修改。 - 流加密模式(如CFB、OFB、CTR)都不需要padding,解密时务必移除padding配置,否则会导致数据异常。
内容的提问来源于stack exchange,提问作者Kabergrammer
相关产品推荐
相关产品推荐

