天天看點

HTTP協定系列(3)---包括WebSocket簡單介紹

一、HTTPS

    HTTP是超文本傳輸協定,那HTTPS是什麼尼?要明白HTTPS是什麼先要明白HTTP的缺點,想一下我們在使用HTTP的時候會有那些缺點尼?

    1.通信使用的明文(不加密),内容可能會被竊聽;

    2.不驗證用戶端或者伺服器的身份,有可能被僞裝;

    3.無法确定封包的完整性,可能已經被串改;

    假如當我們遇到這些情況的時候怎麼處理尼?這時候我們就應該這樣處理HTTP+加密明文+認證身份+封包完整性;這樣就確定了我們通路的安全性和完整性,就是我們所要說的HTTPS,HTTPS就是超文本傳輸安全協定,通常情況下我們是HTTP+TCP進行用戶端和伺服器的通信,這是普通的HTTP協定,HTTPS則是先和SSL通信,然後SSL在和TCP通信,是以說不難想象HTTPS就是HTTP+SSL。那接下來我們介紹一下HTTPS是怎麼進行安全通信的;

  

HTTP協定系列(3)---包括WebSocket簡單介紹

    使用對稱加密確定了用戶端與伺服器資料的安全性,這樣又來一個問題什麼是對稱加密,對稱加密是最快速、最簡單的一種加密方式,加密(encryption)與解密(decryption)用的是同樣的密鑰(secret key)。對稱加密有很多種算法,由于它效率很高,是以被廣泛使用在很多加密協定的核心當中。對稱加密的一大缺點是密鑰的管理與配置設定,換句話說,如何把密鑰發送到需要解密你的消息的人的手裡是一個問題。在發送密鑰的過程中,密鑰有很大的風險會被黑客們攔截。現實中通常的做法是将對稱加密的密鑰進行非對稱加密,然後傳送給需要它的人。那問題又來了非對稱加密是什麼?非對稱加密為資料的加密與解密提供了一個非常安全的方法,它使用了一對密鑰,公鑰(public key)和私鑰(private key)。私鑰隻能由一方安全保管,不能外洩,而公鑰則可以發給任何請求它的人。非對稱加密使用這對密鑰中的一個進行加密,而解密則需要另一個密鑰。比如,你向銀行請求公鑰,銀行将公鑰發給你,你使用公鑰對消息加密,那麼隻有私鑰的持有人--銀行才能對你的消息解密。與對稱加密不同的是,銀行不需要将私鑰通過網絡發送出去,是以安全性大大提高。這樣我們好像将問題全部解決了,資料就可以安全的傳遞了,其實不然這裡還有一個問題如何伺服器的公鑰準确無誤的傳遞給用戶端?這樣是不是誕生了無窮盡的循環,好在給我們提供了一個決解方案,那就是CA憑證,通過它建立我們的信任基點,就可以保證伺服器公鑰被正确的傳遞給用戶端,然後浏覽器可以使用它安全的把對稱加密的密鑰傳遞給伺服器,之後以此密鑰加密需要傳遞的資訊,保證了資料的安全性。可能這裡你還有問題,為什麼不直接都是非對稱加密?原因是非對稱加密的計算效率遠遠不如對稱加密,會造成伺服器壓力過大;這樣我們基本就了解清楚HTTPS怎麼嘛保證資料安全性的;

二、HTTP認證方式

     1.BASIC認證(基本認證)

     1). 用戶端通路一個受http基本認證保護的資源。

     2). 伺服器傳回401狀态,要求用戶端提供使用者名和密碼進行認證。

           401 Unauthorized

           WWW-Authenticate: Basic realm="WallyWorld"

     3). 用戶端将輸入的使用者名密碼用Base64進行編碼後,采用非加密的明文方式傳送給伺服器。

           Authorization: Basic xxxxxxxxxx.

     4). 如果認證成功,則傳回相應的資源。如果認證失敗,則仍傳回401狀态,要求重新進行認證。

      2.DIGEST認證(基本認證)

      1). 用戶端通路一個受http摘要認證保護的資源。

      2). 伺服器傳回401狀态以及nonce等資訊,要求用戶端進行認證。

         HTTP/1.1 401 Unauthorized

         WWW-Authenticate: Digest

         realm="[email protected]",

         qop="auth,auth-int",

         nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",

         opaque="5ccc069c403ebaf9f0171e9517f40e41"

      3). 用戶端将以使用者名,密碼,nonce值,HTTP方法, 和被請求的URI為校驗值基礎而加密(預設為MD5算法)的摘要資訊傳回給伺服器。

           認證必須的五個情報:

     ・ realm : 響應中包含資訊

     ・ nonce : 響應中包含資訊

     ・ username : 使用者名

     ・ digest-uri : 請求的URI

     ・ response : 以上面四個資訊加上密碼資訊,使用MD5算法得出的字元串。

             Authorization: Digest 

             username="Mufasa",  ← 用戶端已知資訊

             realm="[email protected]",   ← 伺服器端質詢響應資訊

             nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",  ← 伺服器端質詢響應資訊

             uri="/dir/index.html", ← 用戶端已知資訊

             qop=auth,   ← 伺服器端質詢響應資訊

              nc=00000001, ← 用戶端計算出的資訊

              cnonce="0a4f113b", ← 用戶端計算出的用戶端nonce

              response="6629fae49393a05397450978507c4ef1", ← 最終的摘要資訊 ha3

              opaque="5ccc069c403ebaf9f0171e9517f40e41"  ← 伺服器端質詢響應資訊

      4). 如果認證成功,則傳回相應的資源。如果認證失敗,則仍傳回401狀态,要求重新進行認證。

     3.SSL用戶端認證

     4.表單認證

三、WebSocket簡單介紹

     WebSocket協定也是建立在HTTP協定上的,是以發起的者仍然是用戶端,但是一但建立WebSocket通信連接配接以後,不論伺服器和用戶端都可以進行發送封包,是以具有已下特點:1.推送功能,支援服務端向用戶端推送資料;2.減少通信量,隻要建立起WebSocket連接配接,就能一直保持連接配接狀态;

          實作WebSocket通信的步驟:

HTTP協定系列(3)---包括WebSocket簡單介紹
    我寫了一個簡單為例子實作了已下WebSocket下載下傳位址是:
HTTP協定系列(3)---包括WebSocket簡單介紹
HTTP協定系列(3)---包括WebSocket簡單介紹

public class FirstWebSocketController : ApiController
    {
        public HttpResponseMessage Get()
        {
            if (HttpContext.Current.IsWebSocketRequest)
            {
                HttpContext.Current.AcceptWebSocketRequest(ProcessWSChat);
            }
            return new HttpResponseMessage(HttpStatusCode.SwitchingProtocols);
        }

        private async Task ProcessWSChat(AspNetWebSocketContext arg)
        {
            WebSocket socket = arg.WebSocket;
            while (true)
            {
                ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]);
                WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);
                if (socket.State == WebSocketState.Open)
                {
                    string message = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
                    string returnMessage = "You send: " + message + ".at" + DateTime.Now.ToLongTimeString();
                    buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(returnMessage));
                    await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
                }
                else
                {
                    break;
                }
            }
        }
    }      

View Code

HTTP協定系列(3)---包括WebSocket簡單介紹
HTTP協定系列(3)---包括WebSocket簡單介紹
<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <script src="~/js/jquery-1.8.3.min.js"></script>
    <script type="text/javascript">
        $(function () {
            var ws;
            $("#btnConnect").click(function () {
                $("#messageSpan").text("Connection...");
                ws = new WebSocket("ws://" + window.location.hostname + ":" + window.location.port + "/api/FirstWebSocket");
                ws.onopen = function () {
                    $("#messageSpan").text("Connected!");
                };
                ws.onmessage = function (result) {
                    $("#messageSpan").text(result.data);
                };
                ws.onerror = function (error) {
                    $("#messageSpan").text(error.data);
                };
                ws.onclose = function () {
                    $("#messageSpan").text("Disconnected!");
                };
            });
            $("#btnSend").click(function () {
                if (ws.readyState == WebSocket.OPEN) {
                    ws.send($("#txtInput").val());
                }
                else {
                    $("messageSpan").text("Connection is Closed!");
                }
            });
            $("#btnDisconnect").click(function () {
                ws.close();
            });
        }
      )
    </script>
</head>
<body>
    <div> 
        <input type="button" value="Connect" id="btnConnect" />
        <input type="button" value="DisConnect" id="btnDisConnect" />
        <hr />
        <input type="text" id="txtInput" />
        <input type="button" value="Send" id="btnSend" />
        <br />
        <span id="messageSpan" style="color:red;"></span>
    </div>
</body>
</html>      

    https://github.com/wangtongzhou520/WebSocket