构造HTTP请求 以及 关于HTTPS的加密

479 阅读7分钟

1.构造HTTP请求

构造HTTP请求有很多种方式.使用html,使用jQuery,使用socket...等等.

这里我们介绍两种.

  1. 使用html
  2. 使用jQuery

1.1.使用html构造HTTP请求

使用html构造HTTP请求,要使用到 form 标签.

这里form标签中的属性有两个.

  1. action :填写数据要返送到的地址.(URL)
  2. method :填写数据发送使用的方法.
    • 这里的方法只有两个 : (GET/POST)

form标签中使用input标签来组织数据.这里input中的属性以下几个.

  1. type
    • text 普通文本
    • password 密码文本
    • submit 按钮
  2. name
    • 提交数据后 数据的KEY
  3. value
    • 按钮上显示的数据

这是一个GET请求.(这里将数据发送到搜狗首页)

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>GET</title>
    </head>
    <body>
        <!--action:url      method:提交方法(只有GET和POST,不区分大小写)-->
        <form action="https://www.sogou.com/index.html" method="get">
            <!--    input中的 name 就是提交后的数据的key-->
            username: <input type="text" name="username"><br>
            password: <input type="password" name="password"><br>
            <input type="submit" value="提交">
        </form>
    </body>
</html>

把method中的GET改为POST,这个请求就变为了一个POST请求.

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>POST</title>
    </head>
    <body>
        <!--action:url      method:提交方法(只有GET和POST,不区分大小写)-->
        <!--将method中的GET改为POST,这个请求就变为了POST请求-->
        <form action="https://www.sogou.com/index.html" method="POST">
            <!--    input中的 name 就是提交后的数据的key-->
            username: <input type="text" name="username"><br>
            password: <input type="password" name="password"><br>
            <input type="submit" value="提交">
        </form>
    </body>
</html>

1.2.使用jQuery构造HTTP请求

这里我们要使用jQuery中的Ajax函数来构造请求.

Ajax即Asynchronous Javascript And XML(异步JavaScript和XML)

1.2.1.Ajax的异步等待

  1. 同步阻塞等待(Scanner)
    • 就是调用了一个方法以后,不再干别的事情
    • 阻塞等待到这个方法结束.得到结果了再继续执行自己的操作
  2. 同步非阻塞等待
    • 调用一个方法后,调用者去干别的事情
    • 但是会时不时回来查看这个方法有没有执行结束.结束了就获取结果
  3. 异步等待(ajax)
    • 调用方法以后,就不再管这个方法了,专心干别的事情
    • 被调用的方法结束后会给调用者反馈.调用者就知道方法结束了,并得到了结果.
  • 虽然 2 和 3类似.但是很明显 2对调用者的开销更大,而 3对调用者来说就更轻量.

简单理解:

  • 同步 :结果是调用者主动关注的.
  • 异步 :结果不是调用者主动关注的.
  • 阻塞 :等待过程中不会干别的事情
  • 非阻塞 :等待过程中会干别的事情

1.2.2.使用jQuery

要使用jQuery,我们就要有jQuery.

有jQuery的方式有很多种.我们这里直接采用 script标签+jQuery的网络链接来使用jQuery.

<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
  • $ : 就是jQuery的本体.
  • $.ajax() : 使用jQuery调用ajax方法
  • ajax中的属性
    • type: 填写发送请求使用的方法.
      • 这里不仅有GET/POST,这里还可以是其他的方法.
    • url: 填写请求发送的目的地址.
    • success: 调用回调函数.没有发生错误的时候,就会调用这个方法.
    • error: 同上,是回调函数.发送错误会被调用.

同样向搜狗首页发送GET请求.

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>jQuery</title>
    </head>
    
    <!--引入jQuery-->
    <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
    <script>
        <!--    通过$来调用ajax函数-->
        $.ajax({
            //ajax不仅支持GET和POST,也支持其他的
            type: 'get',
            url: 'https://www.sogou.com/index.html',
            success: function (body) {
                //success 对应一个回调函数
                //这个函数就会在正确获取到HTTP响应之后,来调用.
                //"异步"
                //回调函数的参数,就是HTTP响应的body部分.
                console.log("获取到响应数据! " + body);
            },
            error: function () {
                //error 也对应一个回调函数
                //这个函数会在请求失败之后触发
                //"异步"
                console.log("获取响应失败!");
            }
        });
    </script>
    
    <!--正常来说这里会出现错误因为浏览器禁止ajax进行跨域访问(跨越多个域名/多个服务器)-->
    <!--如果对方服务器返回的响应中带有相关的响应头,允许跨域访问操作,就是可以正常被浏览器展示的-->
</html>

修改type的值为post,就变为了POST请求.

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>jQuery</title>
    </head>
    
    <!--引入jQuery-->
    <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
    <script>
        <!--    通过$来调用ajax函数-->
        $.ajax({
            //ajax不仅支持GET和POST,也支持其他的
            type: 'get',
            url: 'https://www.sogou.com/index.html',
            success: function (body) {
                //success 对应一个回调函数
                //这个函数就会在正确获取到HTTP响应之后,来调用.
                //"异步"
                //回调函数的参数,就是HTTP响应的body部分.
                console.log("获取到响应数据! " + body);
            },
            error: function () {
                //error 也对应一个回调函数
                //这个函数会在请求失败之后触发
                //"异步"
                console.log("获取响应失败!");
            }
        });
    </script>
    
    <!--正常来说这里会出现错误因为浏览器禁止ajax进行跨域访问(跨越多个域名/多个服务器)-->
    <!--如果对方服务器返回的响应中带有相关的响应头,允许跨域访问操作,就是可以正常被浏览器展示的-->
</html>

1.2.3.Ajax小tap

这里发送请求之后,大家会发现并没有跳转到搜狗首页.会抓包的同学可以观察到,数据报已经返回了.并且状态码也是 200 .那为什么会没有显示呢.

其实是因为,浏览器是禁止ajax进行跨域访问(跨越多个域名/多个服务器)的,我们这里访问搜狗首页其实就跨域访问了.所以浏览器没有展示页面.但也不是完全不可以.

如果对方服务器返回的响应中带有相关的响应头, 允许跨域访问操作 ,那么就可以正常被浏览器展示了.

2.关于HTTPS.

  • HTTPS相当于HTTP的孪生兄弟.
  • HTTP 协议内容都是按照文本的方式明文传输的. 这就导致在传输过程中出现一些被篡改的情况.
  • HTTPS在HTTP的基础上, 引入了一个加密层.(这里的加密不是为了防止被获取,主要是防止篡改)

2.1.关于篡改

关于HTTP的篡改,最广为人知的就是 "运营商劫持" .

运营商劫持有很多种表现.主要因为是明文传输,所以很容易篡改.

例如:我在网页上要下载一个软件.点击了下载链接以后,跳出来的下载链接不是我要下载的软件.这个时候就发生了 运营商劫持 .我要下载的链接被篡改了.

如果只是这样还不算太危险,但是如果我们要传输密码之类的,因为是明文.所以就会很不安全.

2.2.关于HTTPS的加密

"加密" 是什么

加密就是把明文(要传输的信息)进行一系列变换, 生成密文. 解密就是把密文再进行一系列变换, 还原成明文.

HTTPS 要保证数据安全, 就需要进行 "加密". 网络传输中不再直接传输明文了, 而是加密之后的 "密文". 加密的方式有很多, 但是整体可以分成两大类: 对称加密 和 非对称加密

2.2.1.对称加密

对称加密就是客户端和服务端持有同一个 "密钥", 通过这个 "密钥" 能把明文加密成密文, 并且也能把密文解密成明文.这样就可以在传输中使用密文传输.

但是这里也是有困难的 理想很丰满,现实很骨感

image.png

  • 不能所有的客户端和服务端使用同一个 "密钥".
    • 如果所有的都使用同一个 "密钥" 的话,那黑客只需要注册一个客户端就知道了密钥.
    • 这时,所有的美好幻想都是无用的了.

既然不能所有的使用同一个密钥,那就让客户端来约定密钥.

image.png

  • 每个都有单独的密钥的时候,就会被黑客在建立连接的阶段获取到传输的 "密钥" .
    • 让每个客户端和服务端建立连接的时候约定好 "密钥".
    • 但是这个时候,约定密钥的时候就需要使用明文传输.
    • 黑客在约定密钥的阶段获取到了密钥.
    • 后续美好的幻想又是无用的了.

这样了解下来,我们使用对称加密就没有达到我们想要的效果. 于是大佬又提出了新的加密方式: 非对称加密

2.2.2.非对称加密

非对称加密要用到两个密钥, 一个 "公钥", 一个 "私钥".

  • 客户端明文向服务端询问"公钥".
  • 服务器将公钥发送给客户端.
  • 客户端通过 "公钥",将约定好的 "密钥"加密 发送给服务端.
  • 服务端接收到以后加密的"密钥" 以后, 通过私钥解密.
  • 这样双方就得到了密钥.就可以通过密钥传输数据了.

为什么不直接使用公钥和私钥进行数据传输. 那是因为公钥和私钥的运算速度要比对称慢很多.


中间人攻击--现实很骨感.

当我们觉得这样很安全的时候. "黑客" 又出现了.

黑客在客户端向服务端询问公钥的时候切入:

  • 黑客自己也 有一组 "公钥"和 "私钥".
  • 当客户端向服务端询问公钥的时候,黑客就将自己的公钥发送给客户端
  • 客户端拿到这个公钥 傻傻分不清是谁发给他的.但还是把自己约定的 "密钥" 通过这个"安全的公钥" 进行加密并发送给 "服务端"(黑客).
  • 黑客得到这个数据 通过自己的私钥进行解密.就得到了服务端和客户端进行通话的"密钥".
  • 然后黑客再将这个密钥通过 服务端给的公钥进行加密.发送给服务端.
  • 这样黑客就神不知鬼不觉的获取到了密钥.

2.2.2.1.证书

为了防止这种情况.于是有了工信机构.在搭建一个HTTPS网站的时候,首先要在CA机构(工信机构)先申请一个证书.(作为安全的代表).这个证书包含了刚才的公钥, 也包含了网站的身份信息.

  • 在客户端和服务器刚一建立连接的时候, 服务器给客户端返回一个 证书.
  • 客户端获取到证书之后,会对证书进行校验(防止证书是伪造的)
    • 操作系统中已内置的受信任的证书发布机构.所以验证起来很简单.
  • 验证了证书以后,再验证数据是否有被篡改.
    • 具体过程: 从系统中拿到该证书发布机构的公钥, 对签名解密, 得到一个 hash 值(称为数 据摘要), 设为 hash1. 然后计算整个证书的 hash 值, 设为 hash2. 对比 hash1 和 hash2 是否相等. 如果相等, 则说明证书是没有被篡改过的.

这样就解决了上述的黑客入侵的问题.