案情背景 目前公司做新項目,基本所有新項目都是用.net core來做,舊項目一半還是基於 .net framework下麵,一半已經遷移到了core平臺。在做新項目的時候,有個功能需要對接到舊項目那邊的介面,功能也不複雜,就是對接介面的參數需要通過簽名,然後進行MD5加密傳輸過去,舊項目那邊也有相 ...
案情背景
目前公司做新項目,基本所有新項目都是用.net core來做,舊項目一半還是基於 .net framework下麵,一半已經遷移到了core平臺。在做新項目的時候,有個功能需要對接到舊項目那邊的介面,功能也不複雜,就是對接介面的參數需要通過簽名,然後進行MD5加密傳輸過去,舊項目那邊也有相同的簽名和加密方式,用來檢驗參數的正確性,聽起來其實就是一種很簡單傳統的簽名驗證方式,卻因為 “.net core 和 .net framework 下麵編碼不同” 導致走了很多彎路
在傳參過程中,一直收到舊項目介面返回的“簽名錯誤”的提示,剛開始以為是兩者對應的簽名方法不一致,但經過同事確認,簽名方法是直接複製過來的,絕對沒錯(雖然我還是不信ㄟ( ▔, ▔ )ㄏ),為了證明他的結論是錯的,我毅然在 .net framework下麵建了個項目,然後同樣的代碼copy過去,當我run起來後,心裡本來想可以美滋滋的過去扇他一嘴巴子。結果簽名通過了,介面調用成功,這讓我很是惆悵啊.........
肇事方法
回頭整理下,整個過程中,排除了業務方法後,最終最只有這個MD5加密的方法
/// <summary> /// MD5加密 /// </summary> /// <param name="password"></param> /// <returns></returns> public static string MD5Encrypt(string context) { var bytes = Encoding.Default.GetBytes(context); var md5Str = MD5.Create().ComputeHash(bytes); return BitConverter.ToString(md5Str).Replace("-", ""); }
然後我把這個方法單獨拿出來在兩個平臺上測試,發現結果確實不一樣,心裡莫名有種興奮感,接下來定位到 Encoding.Default.GetBytes 這個方法,於是再測試了一次
這是.net core下麵的結果
這是.net framework下麵的結果
尋找真相
發現到這裡,我的第一反應其實是這樣的
接下來,百度和stackoverflow查一下,找不到答案,問了幾個群,也沒人遇到過。然後拿出了殺手鐧,我親愛的谷歌,可能提問方式不對,愣是找不到答案。最後,沒辦法了,是時候發揮一個程式員的精神了,咱自己看下源碼吧,方正.net都是開源的。
第一步,看下.net core下麵 Encoding.Default 這個對象的源碼
可以看到,.net core下麵 Encoding.Default 預設就是獲取了UTF8Encoding這個編碼的
第二步,看下.net core下麵 .net framework這個對象的源碼
可以看到,.net framework 是也有UTF8Encoding這個編碼的,但是確是需要當 代碼頁標識符 為65001的時候才會命中(65001具體表示什麼,等下再說到),這樣看,難道是他們兩個預設的 代碼頁標識符 不一樣,瞬間感覺離真相越來越近了
第三步,看下他們的預設CodePage
.net framework 的
.net core 的
soga~~~果然不一樣,於是查了下963和65001對應的編碼類型
這下就清晰了,雖然同樣都是用 Encoding.Default 的方法,但是由於.net framework 下麵預設的是963(GB2312)的,.net core 下麵是65001(UTF-8)的,所以才會導致相當的方法,跑出了不同的結果。
解決問題
知道原因了就好辦了,由於舊系統的介面之前也會其他系統在對接,所以舊系統那邊的簽名是改不了的,只能改新的這邊,於是只要在.net core 把 Encoding.Default 改作 Encoding.GetEncoding(“GB2312”),統一編碼就可以了,然後興高采烈的run起來,結果居然報錯了,又一次被尷尬到,原來是.NET Core預設不支持GB2312了,所以需要在Starup.cs的Configure方法中加入Encoding.RegisterProvider(CodePagesEncodingProvider.Instance),就這樣妥妥的跑穩了。
好了,感覺是不是有點標題黨,哈哈,其實就是想和大家分享下,也希望大家在.net core 上面遇到的問題也能分享下,可能只是個細節的問題,同樣能幫助別人少才坑。
然後順便跟還在用.net framework的朋友說下,可以 穩穩地轉.net core 了,我已經兩年沒寫過文章了,這兩年來一直在學,在用.net core ,在生產環境中已經穩穩的跑過.net core了,而且是在docker裡面,而且是在k8s裡面(當然linux和window上的就更不用說了)