• 网络知识杂谈


    1. 概述

      1. 简单描述 https
      2. 尽量介绍它的原理
        1. 实际的机制, 可能会更加复杂一些...
      3. 2020-10-07
        1. 回过头来看, 感觉还是很 臃肿 的样子, 怎么能把这些东西讲得简单呢
    2. 背景

      1. 这玩意, 困扰我好多年了
      2. 今天开始, 想做个了断
      3. 之前工作也接触过, 但从我的角度来说, 认识很浅
        1. 会配置
          1. 给个证书, 放好位置, 调一下选项
        2. 会抓包
          1. 开个 charles, 配置几下, 手机挂代理, 安装证书
        3. 具体干啥
          1. 只知道是个 加密的体系
            1. 因为抓包知道, 这不是明文
        4. 机制的理解和思考
          1. 看过 图解http, 没理解就放过去了...
      4. 最后, 将这个东西的时候, 如果你忍无可忍想说一句, 禁止套娃...
        1. 我只能说, 我无能为力...
          1. 我也不想套娃啊...

    1. http 的不足, 与 https 的产生

    1. 概述
      1. 简述两者 关系

    1. http 的不足

    1. 没有状态

    1. 问题
      1. 没有状态, 在识别身份的时候, 就会遇到困难,
    2. 解决
      1. 没关系, 我们有 cookie 和 session
      2. 依靠 客户端 和 服务端, 保存身份信息 到 状态 里
      3. 每一次的交互, 都需要携带这个 不完整的上下文

    2. 依赖连接, 但又没有连接

    1. 问题
      1. http 基于 tcp, 所以通信的时候, 首先要建立起 tcp 连接
        1. 但是 http 传输的内容, 有很多其实是 小内容, 这是 http 头反而是大内容
          1. css
          2. js
          3. ajax 交互的
        2. 然后就是这样
          1. 三次握手创建连接
          2. 收到一个 小玩意
          3. 连接断开
          4. 然后要收下一个, 然后继续 握手
          5. 重复这么几次, 其实很影响客户端的效率
            1. 当然, 之前的服务, 扛不住那么多的长连接...
    2. 解决
      1. keep-alive
        1. 概述

          1. 只要任意一端没有明确提出断开连接,则保持TCP连接状态
        2. 字段

          Connection: keep-alive
          
        3. 结果

          1. 减少了反复连接, 带来的额外等待

    3. 其他问题

    1. 问题

      1. 请求只能从 客户端发起, 服务端只能被动接受
      2. 客户端和服务端之间, 一次只能首发一个请求和响应
    2. 解决

      1. http2
        1. 这个现在还没有全面普及
          1. 现在主要的版本, 是 http1.1
          2. http2 以后还是要学一下

    4. 还有一个问题

    1. 问题

      1. 安全问题
        1. http 的内容, 基本全是明文
          1. 而且 http 报文会在网络里经过 若干跳转, 才能最终传播到 服务器
          2. 如果中途你的报文被拷贝了, 或者被人拦截了, 你的信息全都泄露了...
    2. 解决办法

      1. 部分加密
        1. 这个主要是针对 密码 内容
          1. 场景

            1. 用户在客户端输入密码
            2. 客户端加密密码, 生成一个 密文B
            3. 客户端将密文发送给服务端
            4. 用户注册时, 输入的密码并没有明文保存, 也是用生成密文的方法, 生成了 密文A
            5. 对比 密文A 和 密文B, 就可以得到用户登录的结果
          2. 好处

            1. 避免了 明文传播
          3. 问题

            1. 如果前端加密方式被破解了, 是不是又是明文了
              1. 解决
                1. 可以采用 不可逆 的加密, 比如 md5
                2. 当然, 现在的 md5 可能不那么安全了, 服务端可以再对 md5 的结果 加盐, 然后再做其他
            2. 如果密文被拦截了, 不用密码而用密文, 是不是也能直接登录
              1. 这个我目前解释不了
            3. 如果跟我通信的, 一开始就是个 假服务器, 我有办法吗?
              1. 这个我目前也解释不了
            4. 还有可能, 你的消息在传到你手上之前, 就被别人改了
              1. 这个我目前也解释不了
          4. 或者说

            1. 其实问题 2 和 3, 都是身份确认的问题
              1. 问题2, 本质是 服务端无法确认客户端就是那个 真正的客户端
              2. 问题3, 本质是 客户端无法确认服务端就是那个 真正的服务端
            2. 问题4
              1. 本质上是消息完整性的问题

    2. 问题的解决

    1. 安全问题的解决方案

      1. https
    2. https 解决了什么问题

      1. 消息
        1. 消息的不可见性
        2. 消息的完整性
      2. 通信双方
        1. 客户端的身份认证
        2. 服务端的身份认证
    3. 当然, 一下解决了这么多问题, 毕竟不是一个一句两句, 就能说清楚的东西

      1. 所以, 先说最好理解的东西
        1. 消息的不可见性

    2. 加密的基本常识

    1. 概述
      1. 简单介绍一下加密中会用到的一些常识

    1. 场景: 一个有点类似 写信 的场景

    1. 假定 加密 的应用, 都是在这样的场景下
      1. 角色

        1. 发信人
          1. 知道原文内容
          2. 加密原文, 产生密文
          3. 将密文送给收信人
        2. 收信人
          1. 收获密文
          2. 解密密文
          3. 获取原文中信息
        3. 其他
          1. 可能会有 其他角色, 这个后面说道再补充
        4. 身份问题
          1. 收件人和发件人可以彼此 100% 的确认对方身份
            1. 当然真实环境下, 这个未必
      2. 信息

        1. 原文
          1. 发信人本来想要传达的信息
        2. 密文
          1. 原文经过某种手段, 得到的一个与 原来信息 看起来完全不同的内容
      3. 行为

        1. 加密
          1. 原文 -> 密文
        2. 解密
          1. 密文 -> 原文
      4. 其他

        1. 算法

          1. 加密/解密的过程
            1. 输入
              1. 原文/密文
              2. 密钥
        2. 密钥

          1. 一个特殊的因子
          2. 配合加密/解密算法, 可以得到 原文/密文
        3. 理解

          1. 算法就是一个 function
          2. 原文/密文 和 密钥 是 function 的参数
      5. 概念好像有点多啊...

        1. 最开始, 只打算写 角色 和 信息
        2. 结果怎么 越写越多 了...

    2. 加密的方法

    1. 分类
      1. 可逆
        1. 对称加密
        2. 非对称加密
      2. 不可逆
        1. 这个东西, 后面再说
          1. 之前说的 md5, 就是属于这种

    3. 对称加密

    1. 概述

      1. 加密 和 解密, 使用同样的密钥
    2. 机制

      1. 加密
        1. 输入
          1. 原文
          2. 密钥
        2. 算法
          1. 加密算法
        3. 输出
          1. 密文
      2. 解密
        1. 输入
          1. 密文
          2. 密钥
        2. 算法
          1. 解密算法
        3. 输出
          1. 原文
    3. 特点

      1. 加密
        1. 对于 没有密钥 或者 不知道算法 的第三人来说, 密文就无法理解
      2. 方便
        1. 加密解密用一个 密钥
      3. 双向
        1. 发信人 和 收信人 的身份, 可以互相替换
    4. 问题

      1. 发信人 想和 多个收信人通信, 但又不想 收信人之间 互相知道
        1. 那你每个收信人整个密码呗
          1. 密码多了, 老实说, 不方便管理
          2. 而且, 协商密码, 也是个麻烦事
            1. 如果协商过程被人拦截, 基本也是明文传输
            2. 所以, 协商通常会使用 非对称加密
      2. 又有这么个问题, 发件人如何将这个 公共密钥, 发送给 收件人呢?
        1. 方案1

          1. 思路
            1. 直接发送 密钥 和 密文
          2. 结果
            1. 如果 密钥 被劫, 以后的消息, 搞不好都是明文
        2. 方案2

          1. 思路
            1. 非对称加密
              1. 不得不说, 那帮搞数学的真的牛皮
        3. 这个就是 对称加密 里, 常见的 密钥配送问题

    4. 非对称加密

    1. 概述

      1. 使用 公钥 和 私钥, 对 信息 进行处理
      2. 以 rsa 算法为例
    2. 机制

      1. 公钥 与 私钥
        1. 密钥对

          1. 通常 生成密钥, 是成对的
        2. 公? 私?

          1. 其实本质上, 两个 密钥, 是对等的
          2. 通常的约定
            1. 公钥
              1. 密钥对生成者, 公开出去的密钥
                1. 所有人都知道
            2. 私钥
              1. 密钥对生成者, 自己保存下来的密钥
                1. 只有生成者自己知道
        3. 在 非对称加密 中, 加密和解密需要的密钥不一样

          1. 场景
            1. 公钥加密, 私钥解密
            2. 私钥加密, 公钥解密
          2. 疑问: 加密的密钥, 能在用来解密吗?
            1. 不可以
              1. 在同一个流程里, 它就是不可以
              2. 这个很关键
    3. 场景

      1. 好了, 扯了这么些, 看看这下俩人如何送密码

      2. 步骤

        1. 发信人 让 收信人 送密钥

          1. 这个直接明文传送, 都没关系
        2. 收信人 生成 rsa 密钥对

        3. 收信人 将 公钥, 发送给 发信人

        4. 发信人 收到 公钥

        5. 发信人 生成 对称加密密钥

        6. 发信人 将 对称加密密钥, 用 公钥 加密

          1. 注意, 我们要开始套娃了
        7. 发信人 将 密文发送

        8. 收信人 收到 密文, 用 私钥 解密

        9. 收信人 用 对称加密密钥, 发送 密文

        10. 发信人 收到 密文, 用 对称加密密钥 解密, 确认之后通信开始

    4. 特点

      1. 加密
        1. 自然而然
      2. 稍微有点麻烦
        1. 一套流程, 需要两个 不一样 的密钥
        2. 而且 加密解密 的速度, 没有 对称加密 快
      3. 单向
        1. 通常情况下, 这种通信是单向的
          1. 不是说 公钥私钥 本质上对等吗?
            1. 确实是, 但是如果你 用私钥加密, 有 公钥 的人开起来, 不就是明文了吗?
          2. 所以在这个体系中, 每个人都要有一套自己的 公钥
    5. 现实中, 很多场景都会这样

      1. 用非对称加密, 传递钥匙
      2. 用对称加密来加密解密信息, 进行通信
    6. 又有问题了

      1. 如果 收信人 协商中的有了 中间人, 替换了公钥怎么办
        1. 也就是说, 发信人收到的公钥, 是 中间人 的
          1. 然后 发信人 最后是和 中间人 进行了 加密通信, 还自以为 很安全...
        2. 本质上来说, 就是无法确认 公钥 的真假

    3. 简单的数字证书

    1. 概述

      1. 简述 数字证书模型
        1. 不是真正的 数字证书
    2. 解决思路

      1. 收信人 将自己的公钥, 存放在 权威第三方
        1. 一般来说, 是个 认证中心
      2. 认证中心用 私钥, 将 收件人 的 公钥加密
        1. 注意, 要开始套娃了
        2. 我们把这个 加密后的公钥(套娃), 叫做 证书 吧
        3. 切记, 这不是 现实中的证书
        4. 通常 这个证书, 会保存在 收信人 那里
          1. 简化模型, 方便理解
      3. 发信人 通常会持有 认证中心 的 公钥
        1. 这个一般改不了
          1. 主流浏览器, 自带了 认证中心 的公钥, 一般不会被骗的
      4. 发信人 请求 收信人, 获取证书
        1. 也忘了之前在哪里看到, 是 请求认证中心, 获取证书
          1. 坑了我好多年
      5. 发信人 解密 证书, 获取 收信人公钥
      6. 后面的过程, 就是上面的 非对称加密交换密钥 的过程, 就不再重复了
    3. 问题

      1. 如果有中间人怎么办呢?

        1. 中间人有什么
          1. 中间人也有 认证中心 的公钥
          2. 中间人可以获取 发信人的 通信数据包
        2. 中间人可以干什么
          1. 中间人可以获取 收信人的公钥
            1. 但是有公钥, 除了加密, 你还能干什么呢?
          2. 然后, 好像就没有什么了
        3. 看起来好像, 有那么点安全了
      2. 然而, 中间人 气急败坏又不甘, 他还可以做别的尝试...

        1. 认证中心
          1. 既然叫 认证中心, 不可能只对一个 收信人 做认证吧
          2. 收信人可以注册, 中间人也可以啊
        2. 中间人的新思路
          1. 拦截 收信人 的数字证书, 换成 中间人的数字证书
          2. 拦截 发信人 的加密通信
            1. 此时, 发信人用 中间人的私钥, 加密了 对称密钥
          3. 解析 加密请求
            1. 用的 中间人 的公钥, 中间人当然能解开
          4. 响应 发信人 的请求
          5. 然后两边开会 加密通信...
            1. 发信人自以为在和 收信人 通信, 并且觉得 很安全...
      3. 怎么感觉忽然又 不安全 起来了

        1. 这个时候, 需要引入 数字签名 了

    4. 数字签名

    1. 概述

      1. 简述 数字签名 的机制
    2. 数字签名

      1. 概述

        1. 一段 加密信息
        2. 作用是用来帮助验证 证书的真假
      2. 生成

        1. 前提

          1. 认证中心 获取了 收信人 的 公钥
          2. 假定 认证中心 只使用 md5 作为 摘要 生成手段
        2. 步骤

          1. 将 收信人公钥, 以及 收信人的信息, 使用 md5, 生成一个 摘要
          2. 将 摘要 通过 认证中心 的 私钥, 加密, 生成 数字签名
    3. 真正的数字证书

      1. 内容
        1. 收信人 的 公钥
        2. 收信人 其他身份信息
          1. 比如 url 等, 可以确认身份的信息
          2. 摘要生成方式, 这里默认是 md5
        3. 数字签名
    4. 使用 数字证书

      1. 获取 收信人公钥
      2. 将 收信人公钥 和 相关信息, 使用 md5, 生成 摘要1
      3. 将 数字签名, 用 认证中心 公钥解密, 还原为 摘要2
      4. 比对 摘要1 和 摘要2
        1. 如果相等, 证书就没有被 修改过
      5. 然后继续比对
        1. 证书中身份信息, 这里可以用和当前的通信者进行比对
        2. 如果不符合, 说明证书是假的
    5. 好, 现在来看看, 中间人还能做着呢吗

      1. 假设还想上次一样, 中间人用自己的 证书, 返回 发信人
        1. 结果
          1. 解析出来证书里的 其他身份信息 与 正在访问的地址 不匹配
          2. 中间人窃听失败

    5. 总结

    1. 反思之前为什么没搞懂

      1. 从 2016年 到 2019年都快完了, 我终于把这些原理搞懂了
        1. 之前搞不懂的原因
          1. 对称加密 和 非对称加密, 我是搞明白了的
            1. 简单的原理, 以及 他们解决的问题
          2. 没有理解, 加密 https 的重点
            1. 基础
              1. 发送者 获取 接收者 的公钥, 之后采用 对称加密 通信
            2. 重点
              1. 如何保证 接收者的公钥, 是真实而有效的
          3. 对 认证中心 的工作, 比较模糊
          4. 对 数字签名, 数字证书 的认识, 比较模糊
            1. 再次谴责套娃
          5. 没有采用 循序渐进 的方式, 来理解这些 复杂, 但又有关联的机制
            1. 机制虽然比较多, 但却是 逐步演进
            2. 后一个机制的出现, 都是为了填补前一个机制埋下的坑
            3. 理解了 机制之间的关系后, 机制之间的具体细节, 感觉会稍微清楚一些
          6. 在没有搞清楚机制的情况下, 继续去看 握手
            1. 我当时是有多牛逼, 觉得自己能直接硬啃
    2. 尝试简单整理下 https

      1. 意义

        1. 可靠的加密通信
      2. 基础

        1. 发信人 获取 收信人公钥
      3. 重点

        1. 数字证书的有效性
      4. 难点

        1. 数字证书的组成, 以及验证方式
          1. 数字签名
      5. 实际通信方式

        1. 协商后的 对称加密
          1. 233333

    ps

    1. ref

      1. 即时通讯安全篇(七):如果这样来理解HTTPS,一篇就够了
        1. 这个老哥写的挺好的
          1. 特别是场景的举例, 好些场景我开始没有考虑到, 被他一说, 我觉得挺有道理的...
      2. 图解 http
        1. 16 年看过这本书, 但还是 没看懂
          1. https 这段, 当时觉得很简略
          2. 现在看
            1. 大体流程也说了
            2. 但是对 数字签名 和 数字证书, 说的比较简单
              1. 这个大概是我 困扰的由来 吧
      3. 图解密码学
        1. 之前过了一遍, 内容记不大清了, 但还是记得那是本好书
      4. HTTPS认证解决什么问题,以及实现原理
    2. 持久连接

      1. 意义
      2. 感觉这里, 其实东西不少
        1. channel
        2. 并行传输
    3. https

      1. 原理已经简单说明
      2. 实际的机制, 我想以后有空, 还是要说一下
        1. ssl 和 握手什么的...
    4. 再有个疑问

      1. 既然都这么安全了, 为啥还是可以用 charles 或者 fiddler 来看抓包
        1. 为啥信任一个抓包工具的证书, 就可以看 明文 https 了
        2. 那如果我不小心信任了中间人, 是不是就不行了
    尽量尝试解释清楚; 自己校对能力有限, 如果有错误欢迎指出
  • 相关阅读:
    Android SDK Android NDK 官方下载地址
    编码转换工具 源码
    st_mode的剖析
    关于 python 字符编码的一些认识
    MFC中的argc和argv参数
    VC实现文件拖拽获取文件名
    CString 转 int
    《C语言程序设计实践教程》实验题源程序
    C语言 文件操作 结构体与文件 fgetc fputc fread fwrite
    C++语言 创建状态栏
  • 原文地址:https://www.cnblogs.com/xy14/p/11994528.html
Copyright © 2020-2023  润新知