跨.NET框架下Encoding.UTF8.GetString与GetBytes转换后字节数组长度不一致导致解密失败
跨.NET框架下Encoding.UTF8.GetString与GetBytes转换后字节数组长度不一致导致解密失败
嗨,我来帮你拆解这个问题的核心原因和解决办法!
问题根源
你遇到的问题本质上是用UTF-8编码来处理二进制密文是错误的。加密后的encrypted字节数组是纯二进制数据,里面大概率包含很多UTF-8编码无法识别的字节序列。当你调用Encoding.UTF8.GetString(encrypted)时,.NET会把那些无法解析的字节替换成替换字符(U+FFFD,也就是你可能看到的�)。
虽然后续的UrlEncode和UrlDecode之后,字符串看起来和原来一样,但这些替换字符对应的字节已经和原始密文完全不同了。等到你用Encoding.UTF8.GetBytes(urlDecodedValue)转回字节数组时,就会因为这些替换字符产生额外的字节,导致数组长度从48变成87,密文数据也彻底损坏,解密自然失败。
跨框架(.NET Framework 4.8 vs .NET Core 8)的UTF-8处理细节可能有细微差异,但这不是核心问题——核心是用错了编码方式。
正确解决方案:用Base64编码替代UTF-8
Base64是专门用来将二进制数据转换成安全文本格式的编码方式,能保证数据完整无损,完全适合这种密文传输场景。
修改你的代码如下:
加密端(.NET Framework 4.8)
// 把二进制密文转换成Base64字符串,而非UTF-8字符串 var base64Value = Convert.ToBase64String(encrypted); var urlEncodedValue = WebUtility.UrlEncode(base64Value);
解密端(.NET Core 8)
var urlDecodedValue = WebUtility.UrlDecode(cryptedHeaderValue); // 把Base64字符串转回原始二进制密文 var urlDecodedProtectedData = Convert.FromBase64String(urlDecodedValue);
这样处理后,你得到的urlDecodedProtectedData就会和原始的encrypted字节数组完全一致,解密就能正常工作了。
备注:内容来源于stack exchange,提问作者Wasyster
相关产品推荐
相关产品推荐

