幾週前,我遇到了一個有趣的問題:我必須將 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中文網其他相關文章!