几周前,我遇到了一个有趣的问题:我必须将 AES 加密算法从 C# 迁移到 Go。在Go实现中我们已经有了AES加密算法,但它与C#实现不兼容,多次测试失败,因为结果不匹配,主要是最后一个字符。
问题是我没有 C# 实现的源代码,只有二进制文件,即 .NET 项目中使用的 DLL。
我尝试获取 C# 实现的源代码,但没有成功。由于是一个老项目,没有可用的文档。幸运的是,我的老板是开发这个实现的人,但我不记得具体的细节。然而,我确实知道在 AES 加密过程结束时使用了 base64 编码函数。
有了这个线索,我在.NET中打开了该项目,并安装了JetBrains扩展来反编译源代码,并获得了用于加密信息的库代码。
最后发现问题不是出在AES加密算法上,而是出在base64编码上。
在C#代码中,在AES加密过程结束时,使用以下函数进行base64编码:HttpServerUtility.UrlTokenEncode。
UrlTokenEncode 函数是一个 .NET 函数,它将字节数组编码为 Base64 文本字符串,以便在 URL 中传输。此函数执行三个关键操作来解释结果的差异:
URL 安全 Base64 编码:使用适合 URL 的 Base64 变体,用 - 和 / 替换字符。
填充字符删除:该函数删除通常在标准 Base64 编码中使用的 padding = 字符。
在末尾添加一个数字:该函数在字符串末尾添加一个数字,以指示删除了多少个填充字符。
我发现这一切要感谢 ChatGPT,而不是因为我是 Base64 专家。有了这些信息,我就能够修改 Go 中的实现以与 C# 兼容。
在Go中,使用AES加密信息后,进行base64编码如下:
encode := base64.RawURLEncoding.EncodeToString(paddedBytes)
最后,删除的填充字符数将添加到字符串的末尾:
// Calcular el número de caracteres de relleno (`=`) que se habrían añadido paddingCount := (4 - len(paddedBytes)%3) % 4 // Añadir el conteo de relleno al final de la cadena codificada (como hace UrlTokenEncode de C#) if paddingCount > 0 { encoded += strconv.Itoa(paddingCount) }
在 paddingCount := (4 - len(paggedBytes)%3) % 4 行中,计算填充字符 (=) 的数量,然后将其添加到 Base64 编码字符串的末尾:
简而言之,问题不在于AES加密算法,而在于base64编码。感谢从 ChatGPT 获得的信息,我能够修改 Go 中的实现以与 C# 兼容。在这种情况下,使用 ChatGPT 非常有帮助,因为它节省了我大量的时间和头痛;当然,我必须调整每个答案,直到两个实现的结果相等。
以上是从 C# 到 Go:实现 AES 和 Base64 编码兼容性的详细内容。更多信息请关注PHP中文网其他相关文章!