程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> Socket開發框架之數據加密及完整性檢查,socket數據加密

Socket開發框架之數據加密及完整性檢查,socket數據加密

編輯:C#入門知識

Socket開發框架之數據加密及完整性檢查,socket數據加密


 在前面兩篇介紹了Socket框架的設計思路以及數據傳輸方面的內容,整個框架的設計指導原則就是易於使用及安全性較好,可以用來從客戶端到服務端的數據安全傳輸,那麼實現這個目標就需要設計好消息的傳輸和數據加密的處理。本篇主要介紹如何利用Socket傳輸協議來實現數據加密和數據完整性校驗的處理,數據加密我們可以采用基於RSA非對稱加密的方式來實現,數據的完整性,我們可以對傳輸的內容進行MD5數據的校驗對比。

1、Socket框架傳輸內容分析

前面介紹過Socket的協議,除了起止標識符外,整個內容是一個JSON的字符串內容,這種格式如下所示。

上述消息內容,我們可以通過開始標識位和結束標識位,抽取出一個完整的Socket消息,這樣我們對其中的JSON內容進行序列號就可以得到對應的實體類,我們定義實體類的內容如下所示。

我們把消息對象分為請求消息對象和應答消息對象,他們對應的是Request和Response的消息,也就是一個是發起的消息,一個是應答的消息。其中上圖的“承載的JSON內容就是我們另一個傳輸對象的JSON字符串,這樣我們通過這種字符串來傳輸不同對象的信息,就構造出了一個通用的消息實體對象。

另外這些傳輸的消息對象,它本身可以繼承於一個實體類的基類,這樣方便我們對它們的統一處理,如下圖所示,就是一個通用的消息對象BaseMessage和其中JSON內容的對象關系圖,如AuthRequest是登陸驗證請求,AuthorRepsonse是登陸驗證的應答。

using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { this.RSAPublicKey = rsa.ToXmlString(false);// 公鑰 this.RSAPrivateKey = rsa.ToXmlString(true);// 私鑰 }

例如在服務器端,在客戶端Socket成功接入後,我們就給對應的客戶端發送公鑰請求消息,如下代碼所示。

        /// <summary>
        /// 客戶端連接後的處理(如發送公鑰秘鑰)
        /// </summary>
        /// <param name="client">連接客戶端</param>
        protected override void OnAfterClientConnected(ClientOfShop client)
        {
            //先記錄服務端的公鑰,私鑰
            client.RSAPrivateKey = Portal.gc.RSAPrivateKey;
            client.RSAPublicKey = Portal.gc.RSAPublicKey;

            //發送一個公鑰交換命令
            var request = new RsaKeyRequest(Portal.gc.RSAPublicKey);
            var data = request.PackData();
            client.SendData(data);
            Thread.Sleep(100);
        }

那麼在客戶端,接收到服務端的消息後,對消息類型判斷,如果是公鑰請求,那麼我們需要進行回應,把自己的公鑰發給服務器,否則就進行其他的業務處理了。

        /// <summary>
        /// 重寫讀取消息的處理
        /// </summary>
        /// <param name="message">獲取到的完整Socket消息對象</param>
        protected override void OnMessageReceived(BaseMessage message)
        {
            if (message.MsgType == DataTypeKey.RSARequest)
            {
                var info = JsonTools.DeserializeObject<RsaKeyRequest>(message.Content);
                if (info != null)
                {
                    //記錄對方的公鑰到Socket對象裡面
                    this.PeerRSAPublicKey = Portal.gc.UseRSAEncrypt ? info.RSAPublicKey : "";
                    Console.WriteLine("使用RAS加密:{0},獲取到加密公鑰為:{1}", 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
            {
                //交給業務消息處理過程
                this.MessageReceiver.AppendMessage(message);
                this.MessageReceiver.Check();
            }
        }

如果我們交換成功後,我們後續的消息,就可以通過RSA非對稱加密進行處理了,如下代碼所示。

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("{0}{1}{2}", (char)this.StartByte, json, (char)this.EndByte);

這樣就是我們需要發送的消息內容了,我們攔截內容,可以看到大概的內容如下所示。

上面紅色框的內容,必須使用原有的私鑰才能進行解密,也就是在網絡上,被誰攔截了,也無法進行解開,保證了數據的安全性。

 

3、數據完整性檢查

 數據的完整性,我們可以通過消息內容的MD5值進行比對,實現檢查是否內容被篡改過,不過如果是采用了非對稱加密,這種 完整性檢查也可以忽略,不過我們可以保留它作為一個檢查處理。

因此在封裝數據的時候,就把內容部分MD5值計算出來,如下所示。

data.MD5 = MD5Util.GetMD5_32(data.Content);//獲取內容的MD5值

然後在獲得消息,並進行解密後(如果有),那麼在服務器端計算一下MD5值,並和傳遞過來的MD5值進行比對,如果一致則說明沒有被篡改過,如下代碼所示。

                var md5 = MD5Util.GetMD5_32(message.Content);
                if (md5 == message.MD5)
                {
                    OnMessageReceived(message);//給子類重載
                }
                else
                {
                    Log.WriteInfo(string.Format("收到一個被修改過的消息:\r\n{0}", message.Content));
                }

 

以上就是我在Socket開發框架裡面,實現傳輸數據的非對稱加密,以及數據完整性校驗的處理過程。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved