在前面兩篇介紹了socket框架的設計思路以及資料傳輸方面的內容,整個框架的設計指導原則就是易於使用及安全性較好,可以用來從客戶端到服務端的資料安全傳輸,那麼實現這個目標就需要設計好訊息的傳輸和資料加密的處理。本篇主要介紹如何利用socket傳輸協議來實現資料加密和資料完整性校驗的處理,資料加密我們可以採用基於rsa非對稱加密的方式來實現,資料的完整性,我們可以對傳輸的內容進行md5資料的校驗對比。
前面介紹過socket的協議,除了起止識別符號外,整個內容是乙個json的字串內容,這種格式如下所示。
上述訊息內容,我們可以通過開始標識位和結束標識位,抽取出乙個完整的socket訊息,這樣我們對其中的json內容進行序列號就可以得到對應的實體類,我們定義實體類的內容如下所示。
我們把訊息物件分為請求訊息物件和應答訊息物件,他們對應的是request和response的訊息,也就是乙個是發起的訊息,乙個是應答的訊息。其中上圖的「承載的json內容就是我們另乙個傳輸物件的json字串,這樣我們通過這種字串來傳輸不同物件的資訊,就構造出了乙個通用的訊息實體物件。
另外這些傳輸的訊息物件,它本身可以繼承於乙個實體類的基類,這樣方便我們對它們的統一處理,如下圖所示,就是乙個通用的訊息物件basemessage和其中json內容的物件關係圖,如authrequest是登陸驗證請求,authorrepsonse是登陸驗證的應答。
當然,我們整個socket應用,可以派生出很多類似的request和response的訊息物件,如下所示是部分訊息的定義。
對於非對稱加密的處理,一般來說會有一些效能上的損失,不過我們考慮到如果是安全環境的資料傳輸處理的話,我們使用非對稱加密還是比較好的。
當然也有人建議採用非對稱加密部分內容,如雙方採用約定的對稱加密鍵,通過非對稱加密的方式來傳輸這個加密鍵,然後兩邊採用對稱加密演算法來處理也是可以的。不過本框架主要介紹採用非對稱加密的方式來加密其中的json內容,其他部分常規的資訊不進行加密。
訊息加密資料的傳輸前,我們需要交換演算法的公鑰,也就是伺服器把自己公鑰給客戶端,客戶端收到伺服器的公鑰請求後,返回客戶端的公鑰給伺服器,實現兩者的交換,以後雙方的訊息都通過對方公鑰加密,把加密內容通過標準的socket訊息物件傳遞,這樣對方收到的加密內容,就可以通過自身的私鑰進行解密了。
那麼要在傳遞訊息前處理這個公鑰交換的話,我們可以設計在伺服器接入乙個新的客戶端連線後(在登入處理前),向客戶端傳送伺服器的公鑰,客戶端受到伺服器的公鑰後,回應自己的公鑰資訊,並儲存伺服器的公鑰。這樣我們就可以在登陸的時候以及後面的訊息傳遞過程中,使用對方公鑰進行加密資料,實現較好的安全性。
公鑰傳遞的過程如下圖所示,也就是客戶端發起連線伺服器請求後,由伺服器主動傳送乙個公鑰請求命令,客戶端收到後進行響應,傳送自身的公鑰給伺服器,伺服器把客戶端的公鑰資訊儲存在對應的socket物件上,以後所有訊息都通過客戶端公鑰加密,然後傳送給客戶端。
前面我們介紹過,我們所有的自定義socket物件,都是繼承於乙個basesocketclient這樣的基類物件,那麼我們只需要在它的物件裡面增加幾個屬性幾個,乙個是自己的公鑰、私鑰,乙個是對方的公鑰資訊,如下所示。
在程式的啟動後,包括客戶端啟動,伺服器啟動,我們都需要構建好自己的公鑰私鑰資訊,如下**是產生對應的公鑰私鑰資訊,並儲存在屬性裡面。
using (rsacryptoserviceprovider rsa = new例如在伺服器端,在客戶端socket成功接入後,我們就給對應的客戶端傳送公鑰請求訊息,如下**所示。rsacryptoserviceprovider())
///那麼在客戶端,接收到服務端的訊息後,對訊息型別判斷,如果是公鑰請求,那麼我們需要進行回應,把自己的公鑰發給伺服器,否則就進行其他的業務處理了。///客戶端連線後的處理(如傳送公鑰秘鑰)
/// ///
連線客戶端
protected
override
void
onafterclientconnected(clientofshop client)
///如果我們交換成功後,我們後續的訊息,就可以通過rsa非對稱加密進行處理了,如下**所示。///重寫讀取訊息的處理
/// ///
獲取到的完整socket訊息物件
protected
override
void
onmessagereceived(basemessage message)
,獲取到加密公鑰為:
", portal.gc.usersaencrypt, info.rsapublickey);
//公鑰請求應答
var publickey = portal.gc.usersaencrypt ? portal.gc.rsapublickey : ""
;
var data = new rsakeyresponse(publickey);//
返回客戶端的公鑰
var msg =data.packdata(message);
senddata(msg);
thread.sleep(
100);//
暫停下}
}else
}
data.content = rsasecurityhelper.rsaencrypt(this.peerrsapublickey, data.content);而解密訊息,則是上面**的逆過程,如下所示。
message.content = rsasecurityhelper.rsadecrypt(this.rsaprivatekey, message.content);最後我們把加密後的內容組成乙個待傳送的socket訊息,包含起止識別符號,如下所示。
//這樣就是我們需要傳送的訊息內容了,我們攔截內容,可以看到大概的內容如下所示。轉為json,並組裝為傳送協議格式
var json =jsontools.objecttojson(data);
tosenddata = string.format("
", (char)this.startbyte, json, (char)this.endbyte);
上面紅色框的內容,必須使用原有的私鑰才能進行解密,也就是在網路上,被誰攔截了,也無法進行解開,保證了資料的安全性。
資料的完整性,我們可以通過訊息內容的md5值進行比對,實現檢查是否內容被篡改過,不過如果是採用了非對稱加密,這種 完整性檢查也可以忽略,不過我們可以保留它作為乙個檢查處理。
因此在封裝資料的時候,就把內容部分md5值計算出來,如下所示。
data.md5 = md5util.ge***5_32(data.content);//然後在獲得訊息,並進行解密後(如果有),那麼在伺服器端計算一下md5值,並和傳遞過來的md5值進行比對,如果一致則說明沒有被篡改過,如下**所示。獲取內容的md5值
var md5 =md5util.ge***5_32(message.content);以上就是我在socket開發框架裡面,實現傳輸資料的非對稱加密,以及資料完整性校驗的處理過程。if (md5 ==message.md5)
else
", message.content));
}
C 的Socket開發框架 SuperSocket
supersocket 是乙個輕量級的可擴充套件的 socket 開發框架,可用來構建乙個伺服器端 socket 程式,而無需了解如何使用 socket,如何維護socket連線,socket是如何工作的。該專案使用純 c 開發,易於擴充套件和整合到已有的專案。只要你的已有系統 forum crm ...
Python開發之 Socket程式設計
一 c s架構 c s就是客戶端 服務端的模式,比如瀏覽器就是客戶端,一台伺服器就是服務端,二者進行資料的互動 二 osi七層 應用層 就是我們所用的應用程式 運輸層 這裡需要了解的就是tcp udp協議,這裡就是封裝的tcp協議,也就是你所執行的應用程式的埠號 物理層 用於通訊的介質,比如雙絞線,...
Winform開發框架之資料曲線報表
在專案開發中,往往會碰到一些非常規的需求,每次碰到這種情況,都需要花費時間來整理自己的思路,然後參考網路上其他人的實現方式或者作法,有時候可以找到一些相同的模組進行改進即可符合需求,但往往很多是需要自己潛心研究,然後提煉優化,雖然探索過程還是比較開心,不過時間肯定是需要花不少的。我每次碰到這種情況,...