探讨NET Core数据进行3DES加密或解密弱密钥问题
【導讀】之前寫過一篇《探討.NET Core數據進行3DES加密和解密問題》,最近看到有人提出弱密鑰問題,換個強密鑰不就完了嗎,猜測可能是與第三方對接導致很無奈不能更換密鑰,所以產生本文解決.NET Core中3DES弱密鑰問題,寫下本文,希望對碰到此問題的童鞋有所幫助。
3DES加密或解密弱密鑰
在基于.NET Framework中,我們可以使用反射獲取到TripleDESCryptoServiceProvider的“_NewEncryptor”私有方法,從而規避判斷弱秘鑰問題,但在.NET Core中沒有這個方法,我們首先來看看問題的產生,如下為.NET Core中加密和解密的方法實現
接下來我們調用上述加密方法對數據進行加密,當然這里的密鑰很簡單為16位1,NET Framework中對弱密鑰的具體判斷邏輯這里不做深入分析,如下:
var?desEncryptData?=?DesEncrypt("Jeffcky",?"1111111111111111");為解決這個問題我們下載BouncyCastle.NetCore包,此包有針對基本所有加密算法實現,你會發現通過該包實現和Java中加密算法實現非常相似,若與第三方Java對接,對方所傳數據可能利用.NET Core無法解密或通過加密導致對方無法解密,因為無論是C#還是Java對于算法的實現還是有所差異,利用此包可以進行互操作。
在C#中3DES名稱定義為TripleDES,而在Java中名稱則是DESede,同時C#中的填充模式PKCS7對應Java中的PKCS5Padding,接下來你將看到如下C#代碼幾乎就是從Java中翻譯過來,如下:
static?IBufferedCipher?CreateCipher(bool?forEncryption,?string?key,string?cipMode?=?"DESede/ECB/PKCS5Padding") {var?algorithmName?=?cipMode;if?(cipMode.IndexOf('/')?>=?0){algorithmName?=?cipMode.Substring(0,?cipMode.IndexOf('/'));}var?cipher?=?CipherUtilities.GetCipher(cipMode);var?keyBytes?=?Encoding.UTF8.GetBytes(key);var?keyParameter?=?ParameterUtilities.CreateKeyParameter(algorithmName,?keyBytes);cipher.Init(forEncryption,?keyParameter);return?cipher; }如上主要是創建加密算法接口(默認為3DES),若forEncryption為true表示加密,否則解密,具體細節這里就不再詳細解釋,有興趣的童鞋可自行研究。接下來我們實現加密和解密方法:
雖然密鑰是16位,但在內置具體實現時也會如.NET Core中一樣填充到24位,接下來我們再來調用上述加密和解密方法,看看數據加密和解密是否正確
那么問題來了,為何在C#中會拋出弱密鑰異常,但是在這個包中卻沒能拋出異常呢?內置是基于Schneier pp281的弱和半弱鍵表進行查找可能與C#實現邏輯有所不同(個人猜測),如下:
public?const?int?DesKeyLength?=?8;private?const?int?N_DES_WEAK_KEYS?=?16;//基于Schneier?pp281的弱和半弱鍵表 private?static?readonly?byte[]?DES_weak_keys?= {/*?弱鍵?*/(byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,?(byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,(byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f,?(byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0,?(byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,?(byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,/*?半弱鍵?*/(byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe,?(byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0,?(byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0,?(byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe,?(byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f,?(byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe,?(byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01,?(byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f,?(byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01,?(byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f,?(byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01,?(byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01,(byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0,?(byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1 };public?static?bool?IsWeakKey(byte[]????key,?int?offset) {if?(key.Length?-?offset?<?DesKeyLength)throw?new?ArgumentException("key?material?too?short.");//nextkey:for?(int?i?=?0;?i?<?N_DES_WEAK_KEYS;?i++){bool?unmatch?=?false;for?(int?j?=?0;?j?<?DesKeyLength;?j++){if?(key[j?+?offset]?!=?DES_weak_keys[i?*?DesKeyLength?+?j]){//continue?nextkey;unmatch?=?true;break;}}if?(!unmatch){return?true;}}return?false; }如果第三方為Java,當利用.NET Core實在走投無路無法進行解密時,那就使用上述提供的解密方法進行解密,理論上都可以解密,不能解密的情況大多出現于對C#和Java實現原理不了解導致,如下:
本文重點在于解決.NET Core中3DES弱密鑰問題,同時和第三方對接時實在懶得去理解各語言實現加密算法原理,可嘗試采用上述包來進行互操作,看到有幾位童鞋在文章下提出這個問題而苦于沒找到解決方案,這里提供一種可選擇的方案,都已封裝好,拿去用吧。
總結
以上是生活随笔為你收集整理的探讨NET Core数据进行3DES加密或解密弱密钥问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vue 3拖更,尤雨溪介绍最新进展
- 下一篇: redis大幅性能提升之使用管道(Pip