TCP加密通訊附記,實踐中出現的問題。

在TCP加密通訊的過程,實踐中發現,比之前想的要麻煩一點,那幾個加密類也不是很好用,老是出一些莫名其妙的問題,比如說3des,就老是出莫名其妙的問題,表現在加密二進制字節數組,加密的時候說“數據無效”“無效的填充且無法被移除”之類的,結果換了個aes,據說aes是新一代對稱加密算法,加密強度比3des高,速度快之類的,在.net4下直接有個aes,但是.net4剛出幾天,連win7都不帶,安裝率太低了,大部分都是2.0,但是2.0裏沒有aes,後來發現在.net2裏aes叫Rijndael,用了一下,加密剛纔3des出錯的那個字節數組就沒問題了。

 

另外一個問題就是,加密的時候,凡是

CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write);

cs.Write(bt, 0, count);    

之後

必須要加個cs.FlushFinalBlock();

否則因爲可能字節不夠長度而沒有加密,返回0字節的數組。

 

 

還有本來想的挺美好的一個事情就是CryptoStream cs = new CryptoStream(流, aes.CreateEncryptor(), CryptoStreamMode.Write);

CryptoStream構造函數第一個參數是流,本以爲像

networkstream ns=tcpclient.getstream();

這個ns,可以

CryptoStream csxie = new CryptoStream(ns, aes.CreateEncryptor(), CryptoStreamMode.Write);

CryptoStream csdu = new CryptoStream(ns, aes.CreateDecryptor(), CryptoStreamMode.Read);

加這一句就什麼都不用管了,直接就是加密通訊了

結果發現不行如果客戶這邊用csxie.Write(bt,0,count);csxie.FlushFinalBlock();看似是寫出去了,其實sniffer也能看到是寫出去了,但是服務器那邊如果用csdu.Read(bt,0,bt.Length);讀,就一直卡在這一句,所以就不能實時的加密和解密,如果客戶那邊加一句csxie.clear();服務器那邊就能讀了,但是這句clear卻把整個tcpclient給關閉了,那就沒意義了,所以就比較麻煩了,所以就只能還是用networkstream來讀寫,然後把讀出的數據用CryptoStream來加解密。

這樣又引申出了一個新麻煩,這就要給每個加密的數組標明一個長度
這麼說吧,比如用Rijndael加密“你”字,會得到16個字節,加密“好”字會得到16個字節,分別用Rijndael解密這2個字節數組沒問題,但是你如果把這2個16字節給合成1個32字節的數組用Rijndael解密,就會告訴你“輸入無效”之類的錯誤提示,麻煩就在這裏,比如你加密了一段數據得到了8192個字節,傳出去,那邊正好收到了8192字節,直接解密就不用管了,但是數據是通過網絡傳輸的,你這邊發送8192那邊不一定就一定能一次收到8192個字節的完整數組,如果沒有加密解密比如直接轉發或者寫文件,那收到count個就轉發或寫count個就行了,但是由於要解密就不行了,加密了8192,就一定得解密這8192,多一個少一個都不行,所以每次發送加密數據的時候就得標明這一次加密的數組有多少個字節,如果一次收不全就再收等收全了再解密,如果一次收到了好幾個整段的數組,就得分別解密然後合起來,餘下的不夠整段的要下次接受放在頭裏,這樣一來把完整的網絡通訊過程加解密要比直接傳輸多了大量的計算,而且每次一加解密都要new新的CryptoStream然後關閉。


但是好在cpu比我想象的要快的多的多,並沒有出現想象中的“這樣還能跑的動嗎”的疑問,觀察了一下,經過加密後傳輸和沒有經過加密傳輸無論是服務端還是客戶端的cpu佔用率和內存佔用率基本沒有區別。但是網絡體驗就感覺到了一點延遲,但是問題不大。


誰有好辦法望不吝賜教

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章