项目一 基于密码学(对称加密DES/3DES 非对称加密 消息认证码 数字签名)

发布于:2025-07-01 ⋅ 阅读:(24) ⋅ 点赞:(0)

目录

1. 项目整体架构图

2.数据的加密解密

2.1加密三要素

2.2常用的加密方式

2.2.1对称加密

2.2.2非对称加密

3. 常用的加密算法

3.1 对称加密  

3.2 非对称加密

3.2.1加密算法

3.2.2秘钥交换过程

3.3 Hash算法 (单向散列函数)

4. 消息认证码 -> HMAC

5. 数字签名


1. 项目整体架构图

https -> openssl

protobuf 数据序列化

项目1功能:对网络通信数据进行加解密的模块(金融 教育 网络通信 数据传输 数据的安全性 对数据加密)

1. 基础组件
   - 数据序列化
     - google protobuf
     - 解决数据的跨平台传输
       - 字节序
       - 计算机位数
         - 32位
         - 64位
       - 字节对齐

         struct A
         {
             int a;    // 4
             char b;    // 1
             char cc;
             int c;    // 4
         };


       - 序列化 -> 编码
         - 将原始数据按照某种格式进行封装 -> 特殊的字符串
         - 将特殊字符串发送给对方
       - 反序列化 -> 解码
         - 接收到序列化的特殊字符串 -> 解析    -> 原始数据
         - 安装业务需求处理原始数据
   
   - 套接字通信
     - tcp
     - 线程池 -> 服务器端使用
     - 连接池 -> 客户端使用
       - 多线程的使用
   
   - 共享内存操作 -> shm
     - 进程间通信的一种方式
     - 效率最高
       - 之前讲的进程间通信的方式都需要使用fd
         - 管道
           - 匿名 -> 不需要读磁盘
           - 有名 -> 需要磁盘文件
         - 本地套接字
         - 内存映射区 -> mmap
       - 不需要对磁盘文件进行操作
       -qt中存在共享内存的类


    - 数据库操作
     - 使用的oracle
     - 使用的oracle官方提供的c++接口
       - OCI
  
2. 秘钥协商服务器 && 客户端

   - 客户端两种实现模式
     - 桌面程序 -> Qt
       - 需要将桌面创建搭建起来
       - 写的qt程序
         - 业务逻辑纯C/C++实现都是可以的
     - 终端交互 -> linux终端 -> 上课时候使用这个实现
   - 服务器 -> 后台的守护进程

2.数据的加密解密

2.1加密三要素

明文/密文:明文即原始数据,密文即加密后的数据

秘钥:定长的字符串  对称加密->自己生成 非对称加密->调用对应算法

算法:加密算法 解密算法

举例:

2.2常用的加密方式

2.2.1对称加密

  1. 秘钥较短
  2. 秘钥只有一个,加密解密的秘钥是同一个
  3. 秘钥分发困难 -> 因为秘钥要保密不能泄露,秘钥不能直接在网络环境中进行发送
  4. 加密的效率高,加密强度相对较低
2.2.2非对称加密

  1. 秘钥较长
  2. 秘钥两个,非对称加密算法都有生成密钥对的函数
  3. 密钥对会保存在不同的文件里,一个公钥文件(较小),一个私钥文件(较大),私钥可以推出公钥,公钥(公开的) 私钥(不公开)
  4. 加密解密的秘钥不同。公钥加密,则必须私钥解密;私钥加密,则必须公钥解密
  5. 秘钥可以直接分发 -> 分发的公钥
  6. 效率低,加密强度相对较高

3. 常用的加密算法

3.1 对称加密  

- DES
- 已经被破解了, 不安全
    - 秘钥长度 8byte
  - 对数据分段加密, 每组8字节
    - 得到的密文和明文长度是相同的
- 3DES -> 3重des
    - 安全的, 效率比较低
    - 对数据分段加密, 每组8字节
    - 得到的密文和明文长度是相同的  == 8字节
    - 秘钥长度24字节, 在算法内部会被平均分成3份, == 每份8字节
      - 看成是3个秘钥
      - 每个8字节
    - 加密处理逻辑:
      - 加密:     -> 秘钥1  * 加密算法
      - 解密     -> 秘钥2   * 解密算法
      - 加密     -> 秘钥3   * 加密算法
    - 三组秘钥都不同, 加密的等级是最高的


- AES
  - 最安全, 效率最高的公开的对称加密算法
  - 秘钥长度: 16字节, 24字节, 32字节
    - 秘钥越长加密的数据越安全, 效率越低
  - `分组加密, 每组长度 16 字节`
  - 每组的密文和明文的长度相同  == 16byte
- Blowfish
- RC2/RC4/RC5
- IDEA
- SKIPJACK

3.2 非对称加密

3.2.1加密算法

- RSA(数字签名和密钥交换) ,项目中用的是rsa
- ECC(椭圆曲线加密算法 - 数字签名),效率最高
- Diffie-Hellman(DH, 密钥交换)
- El Gamal(数字签名)
- DSA(数字签名)

3.2.2秘钥交换过程

假设通信的双方为: 客户端C, 服务器端S
为什么要交换?
    1. 非对称加密秘钥分发方便, 但是效率低 -> 改进: 需要使用对称加密
    2. 使用对称加密 -> 秘钥分发困难 -> 改进: 使用非对称加密进行秘钥分发
        - 分发是对称加密的秘钥, 本质就是一个字符串


秘钥交换的过程:
    1. 在服务器端生成一个非对称加密的密钥对: 公钥, 私钥
    2. 服务器将公钥发送给客户端, 客户端有了公钥
    3. 在客户端生成一个随机字符串 -> 这就是对称加密需要使用的秘钥
    4. 在客户端使用公钥对生成的对称加密的秘钥进行加密 -> 密文
    5. 将加密的密文发送给服务器
    6. 服务器端使用私钥解密 -> 对称加密的秘钥
    7. 双方使用同一秘钥进行对称加密通信

3.3 Hash算法 (单向散列函数)

 特点: 

 - 不管原始数据有多长, 通过哈希算法进行计算, 得到的结果的长度是固定的
   - 是一个二进制的字符串
 - 只要是原始数据不一样, 得到的结果就不一样
   - 原始数据差一丢丢, 得到的结果也是完全不同的
 - 有很强的抗碰撞性
   - 碰撞: 原始数据不同, 但是通过同样的哈希算法进行计算能得到相同的结果
   - 推导的结论:
    - 数据不同得到的结果就不同
   - 应用场景:
    - 数据校验,登录验证
    - 秒传
 - 不可逆
   - 得到的结果不能推导出原始数据
 
哈希运算的结果:
- 散列值
 - 指纹
 - 摘要

- MD4/MD5
  - 散列值长度: 16字节
  - 抗碰撞性已经被破解
- SHA-1
  - 散列值长度: 20字节
  - 抗碰撞性已经被破解
- SHA-2
  - sha224
    - 散列值长度: 224bit / 8 = 28byte
  - sha256
    - 散列值长度: 256bit / 8 = 32byte
  - sha384
    - 散列值长度: 384bit / 8 = 48byte
  - sha512
    - 散列值长度: 512bit / 8 = 64byte
- SHA3-224/SHA3-256/SHA3-384/SHA3-512

4. 消息认证码 -> HMAC

作用: 

- 在通信的时候, 校验通信的数据有没有被篡改(完整性)
- 没有加密的功能

使用:

- 消息认证码的本质是一个散列值
- (原始数据 + 秘钥) * 哈希函数 = 消息认证码
  - 最关键的数据: 秘钥

校验的过程:

- 数据发送方A, 数据接收方B
- 在A或B端生成一个秘钥: X, 进行分发 -> A和B端都有了 秘钥: X
- 在A端进行散列值运算:  (原始数据 + x) * 哈希函数 = 得到散列值
- 在A端: 将原始数据和散列值同时发送给B
- 在B端:  -> AB端使用的哈希算法是相同的
  - 接收数据
  - 校验: (接收的原始数据 + x) * 哈希函数 = 散列值New
  - 比较散列值: 散列值New 和 接收的散列值 是不是相同
    - 相同: 没篡改
    - 不同: 被修改了

缺点:

- 秘钥分发困难
- 不能区分消息的所有者

5. 数字签名

作用:

- 校验数据有没有被篡改(完整性)
- 鉴别数据的所有者
- 不能对数据加密

数字签名的过程:  -> 私钥加密数据

- 生成一个非对称加密的密钥对, 分发公钥
- 使用哈希函数对原始数据进行哈希运算 -> 散列值
- 使用私钥对散列值加密 -> 密文
- 将原始数据和密文一起发送给接收者

校验签名的过程:

- 接收签名的一方分发的公钥
- 接收签名者发送的数据:  `接收的原始数据 + 签名`  
- 对数据进行判断:
  - 对接收的原始数据进行哈希运算 -> 散列值new
    - 和签名的时候使用的哈希函数相同(必须相同)
  - 使用公钥对签名(密文) 解密 -> 得到了散列值old
  - 比较两个散列值
    - 相同: 数据的所有者确实是A, 并且数据没有被篡改
    - 不同:  数据的所有者不是A或者数据被篡改了

Bob 自己的私钥,Bob 用自己的私钥对邮件内容计算一个「签名」,将「签名」和邮件内容一起发送出去,接受者 Alice 可以使用 Bob 的公钥验证这个签名是否正确,这就叫「验签」