0


JavaWeb~ajax跨域问题/socket构造请求/Https协议/非对称加密流程/证书机制

文章目录

解决jax跨域问题

如下代码,我们使用ajax发起一个http请求。

<!DOCTYPE html><htmllang="en"><head><metacharset="UTF-8"><title>Title</title></head><body><scriptsrc="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script><script>//基于jQuery 里面的ajax 来进行使用

    $.ajax({//$是jQuery中已经定义好了的一个对象(变量)// jQuery中的所有的api都是$对象的方法
        type:'GET',
        url:'https://www.baidu.com',
        success:function(data,status){//data就是响应的body,status 就是响应的状态码
            console.log(status);
            console.log(data);}});</script></body></html>

当我们将上面代码中的url改成百度的url后,再次运行,就会出现以下情况。
在这里插入图片描述
这就是跨域问题。
即ajax为了保证安全性,要求发起ajax请求的页面,和接受ajax请求的服务器,应该在同一个域名/地址下。
如果 发起请求的页面 对应的域名(假设为域名A)和接受该请求的服务器的域名(假设为域名B)两者不相同,就认为是依次跨域请求。
ajax默认情况下,不允许进行跨域访问。
上面的代码中,域名A对应的是本地域名,而域名B是百度的域名,两者不相同。就被认为是跨域,进行报错。
在上篇博客中,我们使用ajax请求了一个云服务器,虽然在本地页面访问云服务器也是跨域访问,但上次的云服务器经过了特殊处理,解开了ajax不能跨域的限制。
处理如下:
在这里插入图片描述
在服务器代码中配置跨域,就可以允许本地访问该服务器了。

socket构造http请求

HTTP协议也是基于TCP,只不过在TCP的基础之上,按照HTTP约定的格式,构造出一个字符串并发送。我们可以通过Java中的socket来去“拼装”字符串,并发送请求。
代码如下:

import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;publicclassHttpClient{private Socket socket;private String ip;privateint port;publicHttpClient(String ip,int port)throws IOException {this.ip=ip;this.port=port;
        socket=newSocket(ip,port);}public String get(String url)throws IOException {
        StringBuilder request=newStringBuilder();//构造首行
        request.append("GET"+url+"HTTP/1.1\n");//构造请求头header
        request.append("Host:"+ip+":"+port+"\n");//构造空行
        request.append("\n");//GET 请求不需要body

        OutputStream outputStream=socket.getOutputStream();//OutputStream 是一个字节流 ,以字节为单位进行写入// 因此需要把StringBuilder 转换成一个字节数组
        outputStream.write(request.toString().getBytes());//读取响应
        InputStream inputStream=socket.getInputStream();//创建一个1M大小的缓冲区,用来存放响应数据byte[] buffer=newbyte[1024*1024];//n 表示实际读到的字符串int n=inputStream.read(buffer);returnnewString(buffer,0,n);}public String post(String url,String body)throws IOException {
        StringBuilder request=newStringBuilder();//构造首行
        request.append("POST"+url+"HTTP/1.1\n");//构造header
        request.append("Host:"+ip+":"+port+"\n");
        request.append("Context-type:text/plain\n");
        request.append("Content-Length:"+body.getBytes().length+"\n");//构造空行
        request.append("\n");//构造body
        request.append(body);//发送请求

        OutputStream outputStream=socket.getOutputStream();
        outputStream.write(request.toString().getBytes());//读取响应
        InputStream inputStream=socket.getInputStream();byte[] buffer=newbyte[1024*1024];int n=inputStream.read(buffer);returnnewString(buffer,0,n,"utf-8");}publicstaticvoidmain(String[] args)throws IOException {
        HttpClient httpClient=newHttpClient("42.192.83.143",8089);
        String resp= httpClient.get("/AjaxMockServer/info");
        System.out.println(resp);}}

HTTPS协议

什么是HTTPS

HTTPS

全称(

Hypertext Transfer Protocol over Secure Socket Layer

,超文本安全传输协议),HTTPS是通过网络进行安全通信的传输协议,该协议以HTTP协议为基础,引入了一个加密层,使用SSL/TLS来加密数据包。
HTTPS的主要作用是提供对网站服务器的身份认证,来保护数据传输的隐私和完整性。

数据加密相关概念

明文:真正要传输的数据
密文:加密之后的消息
加密:将明文变成密文
解密:将密文变成明文
密钥(yao,四声):在加密和解密的过程中,需要一个中间数据来辅助进行该过程,这样的数据称为密钥

HTTPS的工作过程

为了保证

数据

的安全,就需要进行加密,所以在网络传输中不再直接明文传输,而是传输加密后的密文

加密的方式有很多,但是整体可以分成两大类:

对称加密

非对称加密

对称加密
对称加密其实就是 只通过一个密钥,就可以将明文和密文相互转化。

举例:

我们可以使用异或操作,就可以实现一个简单的对称加密。设明文为8888,密钥为1234,二者异或得到密文 9834.密文和密钥二者异或 就可以解密,得到明文 8888

通过对称加密,我们就可以对数据起到保护作用,即使黑客入侵了路由器,也只能得到请求的密文内容。
在这里插入图片描述
上面的办法虽然好,但有一个缺陷,那就是密钥如何约定呢?我们只能让客户端先生成一个密钥,然后当客户端和服务器连接的时候,将该密钥传递给服务器,让服务器保存。
但如果黑客在服务器和客户端连接时便截取了密钥,那又如何保证数据的安全呢?我们可以对密钥进行加密,传输密钥的密钥.
但这样就陷入了先有鸡还是先有蛋的问题,一直加密下去是行不通 的,故而进入了非对称加密。

非对称加密

非对称加密 是通过 一对密钥,使明文和密文相互转化。
这两个密钥,一个叫做

公钥

,一个叫做

私钥

通过公钥对明文加密,变成密文。
通过私钥对密文解密,变成明文
也可以反着用
通过私钥对明文加密,变成密文。
通过公钥对密文解密,变成明文。

这里的公钥和私钥,可以类比成现实生活中 的信箱~公钥就像信箱上的锁,私钥就像使这把锁的钥匙

非对称加密缺点
运行速度非常慢,比对称加密 慢很多

非对称加密流程

服务器将公钥(公开的密钥)直接发送给客户端。客户端得到公钥后,通过公钥将密钥进行加密,再发送给服务器,服务器通过私钥解密获取到密钥。之后再将收到密钥的消息通过密钥加密后发送给客户端,客户端收到后,就是用该密钥通过对称加密的方式与客户端进行数据传输。
在这里插入图片描述
总结

  • 服务器和客户端连接,将公钥发送给客户端。
  • 客户端在本地生成密钥,然后用公钥加密,发送给服务器。
  • 由于中间的网络设备(如路由器等)没有私钥,即使截获了数据,也无法还原出内部的数据,也就没有办法获得对称密钥。
  • 服务器通过自己保留的私钥解密,还原出客户端发送的密钥,然后用这个密钥将响应数据加密返回给客户端。
  • 后续的客户端和服务器的通信都只用对称加密即可。

引入了非对称加密后,为什么还要继续使用对称加密??
因为

对称加密

对资源的消耗和运行速度都远远低于

非对称加密

,在实际情况中客户端和服务器交互的数据都很大,如果全部使用非对称加密,整体的传输速度就会非常慢。因此我们只需要通过非对称加密让服务器获得密钥即可,之后用对称加密,可以提高传输效率。

仍然存在的问题

客户端如何获取到

公钥


如何保证客户端获取到的

公钥

是真实可靠的,而不是黑客伪造的??

任何人都可以生成一对 公钥和私钥,不仅服务器可以生成,黑客一样可以自己生成

假设以下场景,黑客入侵了中间网络设备,并自己生成了 一对 公钥

pub2

和私钥

pri2

.服务器生成了公钥

pub1

和私钥

pri1

。服务端通过中间设备向服务器请求公钥,服务器返回公钥pub1,被黑客截获,黑客将伪造的公钥pub2发送给客户端。
在这里插入图片描述
接下来客户端用

pub2

对密钥加密,将密文传输给中间设备,黑客此时就可以用

pri2

解密密文,得到真正的密钥,然后继续

pub1

加密密文,再发送给服务器,服务器用

pri1

解密,也拿到了密钥。这时虽然服务器拿到了密钥,但黑客也神不知鬼不觉的情况下也拿到了密钥。所以之后的数据加密传输,就形同虚设,黑客可以直接获取所有的明文数据。
这也叫

中间人攻击


在这里插入图片描述
那如何解决这个问题??
为了解决这个问题,引入了

证书机制

证书机制

在客户端和服务器初次连接时,服务器就给客户端返回一个证书。
这个证书中不仅包含了公钥,也包含了网站的身份信息

工作流程

服务器先生成一对公钥和私钥,然后在第三方机构申请证书,然后服务器将公钥放入证书中,将证书发送给客户端。就算黑客入侵了中间设备,获取了证书,由于证书的校验非常严格,黑客很难伪造一个证书,就算伪造了证书,客户端也可以到第三方机构进行验证。因此客户端可以顺利 拿到真正的公钥,之后加密密钥,发送给服务器。由于黑客没有私钥,截获了数据也无法破译。因此服务器就可以顺利的拿到加密的密钥。

这样就保证了非对称加密的安全问题。
在这里插入图片描述

这个过程也是SSL/TLS的握手过程

证书内容
证书可以看成是一个结构化的字符串,里面包含了以下信息:

  • 证书发布机构
  • 证书有效期
  • 公钥
  • 证书所有者
  • 签名

证书的校验:

  • 判断证书的有效期是否过期
  • 判断证书发布机构是否可信
  • 判断证书是否被篡改(这个判断流程比较复杂,这里不在介绍)

在浏览器中查看证书
chrome浏览器,右上角打开设置,搜索证书,在管理证书页面,点击 受信任的根证书颁发机构中,可以看到当前浏览器中的证书信息。
在这里插入图片描述

总结

HTTPS整个工作过程涉及到的密钥有三组

第一组(非对称加密)

:用于校验证书是否被篡改. 服务器持有私钥(私钥在注册证书时获得), 客户端持有公
钥(操作系统包含了可信任的 CA 认证机构有哪些, 同时持有对应的公钥). 服务器使用这个私钥对证书的
签名进行加密. 客户端通过这个公钥解密获取到证书的签名, 从而校验证书内容是否是篡改过.

第二组(非对称加密)

:用于协商生成对称加密的密钥. 服务器生成这组 私钥-公钥 对, 然后通过证书把公钥
传递给客户端. 然后客户端用这个公钥给生成的对称加密的密钥加密, 传输给服务器, 服务器通过私钥解
密获取到对称加密密钥.

第三组(对称加密)

:客户端和服务器后续传输的数据都通过这个对称密钥加密解密.

参考文章:
https://leheavengame.com/article/622e001dcbba634f3982e4cb

标签: ajax https javascript

本文转载自: https://blog.csdn.net/Merciful_Lion/article/details/123486719
版权归原作者 白菜田田 所有, 如有侵权,请联系我们删除。

“JavaWeb~ajax跨域问题/socket构造请求/Https协议/非对称加密流程/证书机制”的评论:

还没有评论