天天看点

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