【JavaEE初阶】HTTP请求的构造及HTTPS

2023-10-16 15:00:35 浏览数 (1)

1.HTTP请求的构造

常见的构造HTTP 请求的方式有以下几种:

  1. 直接通过浏览器地址栏, 输入一个 URL 就可以构造出一个 GET 请求.
  2. 直接点击收藏夹, 得到的也是 GET 请求.
  3. HTML 中的一些特殊标签也会触发 GET 请求, 如: link, script, img, a…
  4. 还可以通过form表单标签来实现 GET/POST 请求的构造.
  5. 通过 JS 中的 ajax 实现各种请求的构造.

1.1 from表单请求构造

使用 form 表单标签构造请求, action 属性中的 URL 指的是接收请求的服务器地址. 基本格式:

代码语言:javascript复制
<form action="URL" method="http方法类型"></form>

例如使用input标签来构造HTTP请求:

代码语言:javascript复制
<form action="https://www.baidu.com" method="get">
        <input type="text" name="StudentName">
        <input type="submit" value="提交">
</form>

上述代码中,input type = "submit"构造了一个特殊的提交按钮,value属性描述了按钮中的文本.点击这个按钮就会触发该from表单的提交操作.也就是构造http请求发送给服务器.

输入名字,点击提交之后:

我们可以看到,我们构造的这个请求,百度的服务器没有做特别的处理,仍然返回的是百度主页. 打开fiddler,可以看到:

接下来我们构造一个pose请求:

代码语言:javascript复制
<form action="https://www.baidu.com" method="pose">
        <input type="text" name="StudentName">
        <input type="submit" value="提交">
    </form>

对于from构造的post请求来说,body里的数据格式就和query string是非常相似的.也是键值对结构.键值对之间使用&来分割.键和值之间使用=来分割.

值得注意的是,from标签只能构造GET和POST,无法构造PUT,DELET,OPTIONS等方法的请求.

1.2 ajax构造HTTP请求

ajax即Asynchronous Javascript And XML(异步JavaScript和XML)也是浏览器提供的一种,通过js构造HTTP请求的方式.它的功能比from更强.

关于同步和异步的理解: A等待B: 同步:A始终盯着B,A负责关注B啥时候就绪. 异步:A不盯着B,B就绪之后主动通知A.(常见)

html中,通过ajax发起http请求,就属于是"异步"的方式.这一行代码执行"发送请求"操作之后,不必等待服务器响应回来,就立即往下执行.当服务器的响应回来之后,再由浏览器通知到我们的代码中.

代码中使用ajax:

  1. js提供ajax的api,但是原生api不好用(此处不做介绍)
  2. jQuery提供的ajax,api针对原生api的封装.较为简单.

第一步, 引入 jQuery, 搜索 jQuery cdn, 找到一个 jQuery cdn 文件的 URL, 我们选择 min 版本的, 比如我这里得到的是 https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js. 第二步, 使用 $ 对象中的 ajax 函数, 传入一个 js 对象作为参数, 这个对象里面需要包含 HTTP 方法类型 type, 请求的 url, 请求成功后该做什么 success, 失败后该做什么 error

代码语言:javascript复制
<!-- 引入query -->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
        $.ajax({
            type:'get',
            url:'https://www.baidu.com?studentName=zhangsan',
            // 此处的success就声明了一个回调函数,就会在服务器响应返回到浏览器的时候触发该回调.
            //此处的 回调 体现了 异步
            success:function(data){
                console.log("当服务器返回的响应到达浏览器之后,浏览器触发该回调,通知到我们的代码中");
            }
        });
        console.log("浏览器立即往下执行后续代码");
    </script>

但是运行后我们可以看到:

该代码直接执行只能看到构造的请求,无法获取到正确的响应.因为我们发送请求给百度服务器,百度的服务器没有处理我们的请求.

构造请求的顺序是从上到下的.但是收到响应的顺序/触发回调的顺序不确定.

ajax 相比于 form 标签功能更强, 构造请求更加灵活, form 只支持 get 和 post 请求的构造, 而 ajax 还支持 put, delete等, ajax 还可以灵活的设置 header 和body.

1.3 Postman的使用

Postman是谷歌的一款接口测试插件, 它使用简单, 支持用例管理, 支持get, post, 文件上传, 响应验证, 变量管理, 环境参数管理等功能, 可以批量运行, 并支持用例导出, 导入. Postman下载(官网) 下载好后可去’使用邮箱去注册一个账号进行登录 进入后创建一个工作空间:

创建好后,再点击 创建一个标签页:

熟悉页面:

除此之外,Postman还可以生成构造请求的diamante,方便在我们自己的代码中集成.

在此可以选择使用哪种语言构造HTTP请求.

2. HTTPS

2.1 什么是HTTPS?

在网络传输过程中, 存在着运营商劫持和一些黑客入侵这样的危险, 在之前只有HTTP的明文传输数据环境下, 这样的问题是有些泛滥的, 这种情况下就不清楚在中间传输过程中就被哪一服务器将数据篡改了, 所以在后来就引入了HTTPS.

HTTPS (全称: Hyper Text Transfer Protocol over Secure Socket Layer), 就是 HTTP 安全层(SSL), 是以安全为目标的 HTTP 通道, 简单讲就是 HTT P的安全版本, 即 HTTP 下加入 SSL 层, HTTPS 的安全基础是 SSL.

HTTPS 和 HTTP 一样, 都是应用层协议, HTTPS 相比于 HTTP 多了一个加密的功能, 就是在 HTTP 基础上引入了SSL/TLS 加密机制, 该功能作用不是防止数据被窥察, 而是为了防止数据被篡改, HTTP 是明文传输, HTTPS 是密文传输, HTTPS 可以更好地保护数据的传输.

如何理解这里的安全?

安全这个概念只是相对而言, “道高一尺, 魔高一丈”, 不管安全措施如何完善, 相信总是有更厉害的大佬有针对攻击办法, 但我们认为, 网络传输中, 只要黑客解密的成本超过了数据本身的价值, 就认为是安全的了.

这里有几个专有名词需要了解一下

明文: 传输的原始数据. 密文: 原始数据被加密后的数据. 密钥: 可以将明文转换成密文, 也可以将密文转换为明文的 “钥匙”.

2.2 HTTPS中的加密机制(SSL/TLS)

HTTPS 引入的加密层, 称为 SSL 或 TLS, 在 SSL 中加密的机制主要有两种:

  1. 对称加密
  2. 非对称加密

SSL/TLS 部分其实并不是只在 HTTPS 中使用, 在其他的场景中也会用到(比如 SSH 协议, JDBC 等).

2.2.1 HTTP的安全问题

HTTP 是明文传输的, 当有黑客或者运营商从中作梗, 就可以直接篡改客户端和服务器之间传输的数据, 此时就没有什么安全性可言, 客户端和服务器拿到什么样的数据完全就是黑客说了算了.

也就是说, 只要网络上的数据是明文传输的, 都是存在被劫持, 被篡改的风险的, 所以为了能够改善这种问题, 就引入了加密, HTTPS 就应运而生了.

2.2.2 对称加密

对称加密就是客户端和服务器使用相同的密钥对密文进行加密与解密, 密钥就可以认为是一串数字/字符串, 加密就是把明文 (HTTPS 中就是针对 HTTP 的各种 header 和 body) 和密钥字符串进行一系列的数学变换.

a(明文) key = b(密文), 这是加密的过程

b(密文) key = a(明文), 这是解密的过程

要注意, 这里密文传输安全的前提是黑客并不知道密钥是什么, 这就要求不同的客户端使用的是不同的密钥才行, 因为如果不同客户端使用的是相同的密钥, 那么黑客只需要自己启动一个客户端就能拿到密钥, 成本不高, 就没什么安全可言了.

所以, 不同的客户端需要有不同的密钥, 这个密钥要么由服务器生成, 要么由客户端生成, 假设我们这里是由客户端生成密钥, 客户端生成密钥后就需要在传输数据之前需要先将密钥发送给服务器, 即如下过程:

这样不同的客户端就使用了不同的对称密钥来对数据进行加密, 那么当客户端生成对称密钥后, 先将对称密钥传输到服务器, 服务器拿到密钥后再进行业务数据的传输, 之后就使用从客户端拿到的密钥进行数据的加密和解密了. 但此时还是有问题的, 一开始密钥传输的安全问题如何得到保障呢? 在此时的场景下, 密钥刚刚生成, 也就是服务器还不知道密钥是什么, 所以这次密钥的传输还是只能使用明文传输, 很容易就被黑客拦截获取了, 这样的加密也就形同虚设了, 所以就引入了下面的 “非对称加密”.

2.2.3 非对称加密

为了让密钥安全的传输到服务器, 就需要对密钥也进行加密.

对于非对称加密, 它拥有两个密钥, 一个公钥和一个私钥, 其中公钥 “人人” 都能获取到, 而私钥是构造私钥的 “人” 才知道.

相当于我们现实生活中的锁与钥匙, 而这个锁就相当于公钥, 钥匙就相当于私钥.

其中公钥是用来加密的, 而私钥是用来解密的.

明文 公钥 = 密文 密文 私钥 = 明文

此时, 就可以使用非对称加密了, 首先客户端会向服务器询问服务器的公钥是什么, 然后服务器会向客户端发送一个公钥, 客户端收到公钥后会使用这个公钥对客户端构造的对称密钥进行加密, 然后会把加密后的对称密钥传输给服务器, 服务器使用私钥解密得到客户端的对称密钥, 之后的业务数据就可以使用这个对称密钥进行加密和解密了(对称加密).

注意的是,非对称加密只是用来传输密钥的,一旦对称密钥到达服务器之后,后续的传输都是使用对称密钥来加密和解密. 那么为什么有了非对称加密,还要继续使用对称加密呢? 这是因为使用对称加密传输的速度是比较快的,而非对称加密速度就慢很多.实际场景会要求尽可能提高整体的速度,使用对称加密更为合适.

2.2.3 中间人问题

有了上面的非对称加密, 数据传输的安全其实还是存在问题的, 可能会存在 “中间人” 问题, 这个中间人对于服务器会伪装成 "客户端"的身份, 对于客户端, 中间人就会伪装成 “服务器”;

当服务器发送自己的公钥给客户端,中间人也会生成一对公钥与私钥,中间人就把服务器的公钥换成自己的公钥,然后客户端使用中间人的公钥加密对称密钥,然后发送给服务器,此时中间人就可以通过自己的私钥获得对称密钥,获取密钥后中间人会将密钥使用服务器的公钥在加密发送给服务器.

此时数据传输又变成"透明"的了,在之后的对称加密传输过程中,中间人已经知道了对称密钥,就可以将客户端请求/服务器响应的密文数据解密得到原始数据,中间人就可以针对原始数据进行篡改,然后再加密发送,这样中间人就能够拿到客户端和服务器之间的传输数据,可以进行查看和篡改.

2.2.5 证书

中间人问题的解决方案是引入一个第三方工信机构, 现在的服务器 (网站) 一般在设立之初, 就需要去专门的认证机构, 申请证书, 服务器先提供资质证明给工信机构, 工信机构通过审核后, 会给服务器发送一个证书, 该证书不是普通的证书, 里面含有一些校验机制 (校验的过程类似 TCP/UDP 的校验和), 然后服务器会把自己的公钥放入证书中, 客户端也不再询问公钥, 而是询问服务器证书, 得到证书后会去查该证书是否合法, 如果合法才会使用服务器证书中的公钥去进行对密文请求与密钥的加密, 并发送给服务器, 如果不合法浏览器就会弹窗警告.

这个过程就类似于我们使用的身份证来证明身份, 派出所就是第三方的认证机构, 身份证是无法被其他地方生成或者篡改的, 其他人就可以通过身份证来辨识我们的身份.

那么客户端是如何对证书进行验证的呢? 实际上, 操作系统是会内置一些工信机构的信息(包含工信机构的公钥)的.

首先我们需要知道证书上面会有一个特定的字段, 叫做证书的签名, 这个签名是一个被加密的字符串, 是通过对证书中所有的属性, 计算出来的一个校验和(签名), 再由颁布证书的工信机构使用它的私钥对这个签名进行加密.

证书 字段1:abc 字段2:cde 字段3:okm 公钥:0x112233

签名:dgiuwdhqduhouiqdhq

此处的签名就是被加密的字符串. 客户端就可以使用认证机构提供的公钥进行解密,解密之后,得到的结果相当于是一个hash1值.(类似于tcp udp里的校验和 根据证书的其他字段综合计算出来的结果) 客户端可以使用同样的hash算法,针对其他字段再算一次hash值,得到hash2. 看看hash1(从签名中解出来的)和hash2(客户端自己算的)值是否相同.相同就是没有被篡改过的.

黑客即使把证书中服务器的公钥篡改替换成自己的公钥, 然后黑客再针对证书中的各个属性, 重新计算签名, 下一步, 黑客就需要把签名重新加密, 这里黑客就无能为力了, 因为想要加密, 黑客就必须知道工信机构的私钥, 显然, 黑客是无法知道的.

0 人点赞