HTTP与HTTPS(详谈TLS秘钥协商过程)

1. 简单http服务器

#pragma once 

#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<string>
#include<cstdlib>
#include<strings.h>
#include<netinet/in.h>
#include<signal.h>
using namespace std;
class HttpServer
{

  private:
    int _port;
    int _lsock;
  public:
    HttpServer(int p)
      :_port(p)
      ,_lsock(-1)
  {}
    void InitServer()
    {
      signal(SIGCHLD,SIG_IGN);
      _lsock=socket(AF_INET,SOCK_STREAM,0);
      if(_lsock < 0)
      {
        cout<<"socket error"<<endl;
        exit(2);
      }

      struct sockaddr_in local;
      //清零
      bzero(&local,sizeof(local));
      local.sin_family= AF_INET;
      local.sin_port=htons(_port);
      local.sin_addr.s_addr=INADDR_ANY;
      if(bind(_lsock,(struct sockaddr*)&local,sizeof(local)) < 0)
      {
        cout<<"bind error"<<endl;
        exit(3);
      }
      if(listen(_lsock,5) < 0)
      {
        cout<<"listen error"<<endl;
        exit(4);
      }  
    }
    void echoHttp(int sock)
    {
     char request[2048];
     size_t s=recv(sock,request,sizeof(request),0);
     if(s > 0)
     {
       request[s]=0;
       cout<<request<<endl;


       string response="HTTP/1.0 303 Jump\r\n";//响应行
       response += "Content-type: test/html\r\n";//报头
       //response += "location: https//www.baidu.com";
       response += "\r\n";//空行
       response += "\
         <!DOCTYPE html>\
         <html>\
         <head>\
         <title>xust</title>\
         </head>\
         <body>\
         <h1>welcome</h1>\
         <p>niubi</p>\
         </body>\
         </html>";
         send(sock,response.c_str(),response.size()-1,0);
     }
     close(sock); 
    }
    void start()
    {
       
        struct sockaddr_in peer;
        bzero(&peer,sizeof(peer));
        for(;;)
        {
          socklen_t len=sizeof(peer);
          int sock=accept(_lsock,(struct sockaddr*)&peer,&len);
        if(sock < 0)
        {
          cerr<<"accept error"<<endl;
          continue;
        }
        cout<<"get a new connect"<<endl;
        if(fork()==0)
        {
          close(_lsock);
          echoHttp(sock);
          exit(0);
        }

        } 
    }
    ~HttpServer()
    {
      if(_lsock!=-1)
      {
      close(_lsock);
      }
    }
};


先使用telnet测试一下
在这里插入图片描述

在使用手机访问浏览器访问,可以看见请求报头
服务器接收到的客户端的request
在这里插入图片描述

在实验中我们将http的代码,直接写在了string的缓冲区里,而实际上网页是放在web根目录中,通过读文件来获取。

2. 状态码

状态码是给页面的参考值,比如404,代表着not found,只是给浏览器一个参考,这时候由程序员实现一个404错误页面。

2.1 网页重定向

网页重定向分为临时重定向和永久重定向。

301代表永久重定向:
被请求的资源已永久移动到新位置。服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置
302代表临时重定向
服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

对应的请求报头为location
在这里插入图片描述
用fiddler工具抓包。
这里可以故意将状态码描述写错,可以看出状态码只是一种参考。
在这里插入图片描述
location重新跳转到了百度。

3. http与https

3.1 http缺陷

http虽然很快,但是HTTP传输的内容是没有经过加密的,因此用户层的一些隐式数据很容易就被暴露,主要有以下几种不足:
1.通信使用明文(不加密),可能被窃取
2.不验证通信方的身份,因此可能遭遇伪装
3.无法验证报文的完整性,所以有可能遭到篡改

3.2 https与http的区别

http:80
https:443

这两个东西其实是一套安全协议,SSL是非标准的。https诞生时,被并入到https协议中,重新命名为TLS。
可以理解为,在http时,向下交付数据是直接交付,抓包可以抓取到数据,而https中,向下交付数据时,先交给TLS加密,然后在向下交付。
也就是在htpps协议,TLS在应用层和传输层中间。

3.3 对称加密

用一个秘钥进行加密,解密,成为对称加密。
在这里插入图片描述
那么又引入一个问题,秘钥也是数据,怎么保证秘钥的安全。

3.4 非对称加密

通常来说,公钥是用来加密,私钥只能用来使用来解密的。
在这里插入图片描述

那么为什么不一开始就用,服务器给的公钥进行加密,让其用服务器内部非对称私钥解密呢?
原因是,非对称加密算法比较复杂,效率比较低,对称加密简单,效率快。

还有一种场景,假如中间服务器是一个黑客
在这里插入图片描述
类似于fiddler

那么就引发两个问题

  1. 中间信息被篡改的问题?
  2. 远端服务器身份认证问题?

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楠c

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值