Node.js加密XOR-Base64文本后Go语言无法解密的问题求助
解决Node.js与Go语言跨语言XOR加解密兼容问题
这个问题的核心是Node.js和Go对字符串的编码处理逻辑不一致,导致异或操作的基础单元不匹配:
- Node.js里的
charCodeAt()获取的是字符的UTF-16编码单元(每个单元对应16位/2字节,常用字符都属于这个范围) - Go语言直接通过
input[i]访问字符串时,拿到的是UTF-8编码的单字节——如果字符是多字节UTF-8编码(比如中文),这会把一个字符拆成多个字节处理,和Node.js的逻辑完全错位
修正后的Go语言解密代码
我们需要让Go端对齐Node.js的编码逻辑:先把解密后的字节转成UTF-16编码单元,执行异或后再转回UTF-8字符串,具体代码如下:
package main import ( "encoding/base64" "fmt" "unicode/utf16" ) func main() { // 替换成Node.js加密输出的base64字符串 actualInput := "你的加密base64内容" key := "XXXXXX" // 与Node.js使用的密钥保持一致 // 第一步:base64解码 bytes, err := base64.StdEncoding.DecodeString(actualInput) if err != nil { fmt.Println("base64解码失败:", err) return } // 第二步:将UTF-8字节转成UTF-16编码单元(对齐Node.js的charCodeAt) inputUTF16 := utf16.Encode([]rune(string(bytes))) keyUTF16 := utf16.Encode([]rune(key)) keyLen := len(keyUTF16) // 第三步:执行XOR解密 decryptedUTF16 := make([]uint16, len(inputUTF16)) for i := range inputUTF16 { decryptedUTF16[i] = inputUTF16[i] ^ keyUTF16[i%keyLen] } // 第四步:将UTF-16转回UTF-8字符串 decryptedStr := string(utf16.Decode(decryptedUTF16)) fmt.Println("解密结果:", decryptedStr) }
关键逻辑对齐说明
- 编码统一:
Node.js中从base64解码后得到UTF-8字符串,再通过charCodeAt取UTF-16编码单元;Go端通过utf16.Encode把UTF-8字符串转成对应的UTF-16单元切片,确保异或的操作单元完全一致。 - 密钥处理:
密钥在Node.js中同样是按UTF-16单元参与异或,所以Go端也要把密钥转成UTF-16单元切片再使用。 - 结果还原:
解密后的UTF-16单元切片通过utf16.Decode转回rune数组,再转成UTF-8字符串,得到最终明文。
测试验证示例
用Node.js加密测试内容:
const key = "XXXXXX"; const data = "测试内容Test Content"; const encrypted = B64XorCipher.encode(key, data); console.log(encrypted); // 输出加密后的base64字符串
将这个base64字符串填入Go代码的actualInput,运行后就能得到正确的解密结果测试内容Test Content。
内容的提问来源于stack exchange,提问作者Soorya Prakash
相关产品推荐
相关产品推荐

