Home > Article > Backend Development > From C# to Go: Achieving AES and Base64 Encoding Compatibility
A couple of weeks ago I faced an interesting problem: I had to migrate an AES encryption algorithm from C# to Go. In the Go implementation we already had an AES encryption algorithm, but it was not compatible with the C# implementation, and several tests failed because the results did not match, mainly in the last character.
The problem was that I did not have the source code of the C# implementation, only the binary, a DLL that was used in the .NET project.
I tried to get the source code of the C# implementation, but was unsuccessful. Being an old project, there was no documentation available. Fortunately, my boss was the one who developed this implementation, but I didn't remember the exact details. However, I did know that at the end of the AES encryption process a base64 encoding function was used.
With this clue, I opened the project in .NET and installed the JetBrains extension to decompile the source code, and obtained the library code that was used to encrypt the information.
Finally, I discovered that the problem was not with the AES encryption algorithm, but with the base64 encoding.
In the C# code, at the end of the AES encryption process, the following function was used for base64 encoding: HttpServerUtility.UrlTokenEncode.
The UrlTokenEncode function is a .NET function that encodes a byte array into a base64 text string for transmission in a URL. This function performs three key actions that explain the difference in results:
URL-safe Base64 encoding: uses a variant of Base64 that is suitable for URLs, replacing the characters with - and / with _.
Padding Character Removal: The function removes padding = characters that are typically used in standard Base64 encoding.
Adding a number to the end: The function adds a number to the end of the string to indicate how many padding characters were removed.
I discovered all this thanks to ChatGPT, not because I am an expert in base64. With this information, I was able to modify the implementation in Go to be compatible with that of C#.
In Go, after encrypting the information with AES, base64 encoding is done as follows:
encode := base64.RawURLEncoding.EncodeToString(paddedBytes)
And finally, the number of removed padding characters is added to the end of the string:
// 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) }
In the line paddingCount := (4 - len(paddedBytes)%3) % 4, the number of padding characters (=) is calculated and then added to the end of the base64-encoded string:
In short, the problem was not the AES encryption algorithm, but the base64 encoding. Thanks to the information obtained from ChatGPT, I was able to modify the implementation in Go to be compatible with that of C#. In this case, using ChatGPT was very helpful as it saved me a lot of time and headaches; Of course, I had to adjust each answer until the results of both implementations were equal.
The above is the detailed content of From C# to Go: Achieving AES and Base64 Encoding Compatibility. For more information, please follow other related articles on the PHP Chinese website!