OPENSSL-2023/11/10学习记录-C/C++对称分组加密DES

image.png

image.png

image.png

image.png

image.png

  • 对称分组加密常用算法:

·DES
·3DES
·AES

·国密SM4

  • 对称分组加密应用场景:

文件或者视频加密

加密比特币私钥

消息或者配置项加密

SSL通信加密

对称分组加密

使用异或实现一个简易的对称加密算法

A明文 B秘钥
AB=密文AB
(AB)B =A

密码补全和初始化
数据补全策略:PADDING_PKCS7(补其他) PADDING_ZERO(补0)

举例:

block = 8

12345678 9
12345678 90000000 ZERO

12345678 97777777 PKCS7

更详细请看:DES加密初探 - 乙太的小屋 (52ying.top)DES算法填充方式

#include <iostream>using namespace std;//对称加解密数据
//@para data 输入数据
//@para data_size 输入数据大小
//@para out 输出数据
//@para pass 密钥
//@para pass_size 密钥长度
//@return  加解密后数据大小
#define XOR_BLOCK 8
int XorCipher(const unsigned char* data, int data_size,unsigned char* out,const unsigned char* pass,int pass_size
) 
{static const char iv[] = "abcdefgt";//初始化密钥auto p = *(unsigned long long*)iv;//密钥补全,并且异或初始化向量//密钥小于XOR_BLOCK或者大于XOR_BLOCKfor (int i = 0; i < pass_size; i += XOR_BLOCK){unsigned long long tmp = 0;int size = XOR_BLOCK;//密钥小于 XOR_BLOCKif (pass_size - i < XOR_BLOCK) {size = pass_size - i;}memcpy(&tmp, (pass + i), size);p = (p ^ tmp);}//数据源转换成8字节数据类型auto d = (unsigned long long*)data;//输出数据auto o = (unsigned long long*)out;//数据分组处理int i = 0;for (; i < data_size / XOR_BLOCK; i++){o[i] = (d[i] ^ p);}//输入数据的补充int mod = data_size % XOR_BLOCK;if (mod != 0){unsigned long long tmp = 0;memcpy(&tmp, (d + i), mod);}int re_size = data_size;return re_size;
}int main1(int argc, char* argv[])
{unsigned char data[] = "测试加解密数据TEST123测试";unsigned char out[1024] = { 0 };unsigned char out2[1024] = { 0 };unsigned char pass[] = "12345678";int pass_size = strlen((char*)pass);int len = XorCipher(data, sizeof(data),out, pass, pass_size);cout << len << "|"<<out << endl;len = XorCipher(out, len, out2, pass, pass_size);cout << len << "|" << out2 << endl;return 0;
}

DES_ECB攻击

#include <iostream>
#include <openssl/des.h>
using namespace std;//交易数据
struct Slip
{char from[16] = { 0 }; //A=>B 10000char to[16] = { 0 };	//篡改为B=> 10000long long amount = 0;};static const_DES_cblock key = "1234567";
static DES_key_schedule key_sch;void EnSlip(const Slip& s, unsigned char* out, int& out_size)
{const int size = sizeof(s);auto p = (const unsigned char*)&s;auto o = out;DES_set_key(&key, &key_sch);for(int i = 0; i < size; i += 8){DES_ecb_encrypt((const_DES_cblock*)p, (DES_cblock*)o, &key_sch, DES_ENCRYPT);p += 8;o += 8;out_size += 8;}
}void AttackSlip(unsigned char* out)
{//修改秘文的from和to对调unsigned char tmp[1024] = { 0 };//frommemcpy(tmp, out, 16);memcpy(out, out + 16, 16);memcpy(out + 16, tmp, 16);}void DeSlip(const unsigned char* in, int size, Slip& s)
{auto p = (const unsigned char*)in;auto o = (unsigned char*)&s;DES_set_key(&key, &key_sch);for (int i = 0; i < size; i += 8){DES_ecb_encrypt((const_DES_cblock*)p, (DES_cblock*)o, &key_sch, DES_DECRYPT);p += 8;o += 8;}
}int main()
{{unsigned char out[1024] = { 0 };int out_size = 0;Slip s1 = { "USER_A","USER_B",10000 };cout << "s2 from: " << s1.from << endl;cout << "s2 to: " << s1.to << endl;cout << "s2 ammout: " << s1.amount << endl;EnSlip(s1, out, out_size);cout << "En:"<< out_size <<"---->" << out << endl;//攻击密文1AttackSlip(out);Slip s2;DeSlip(out, out_size, s2);cout << "s2 from: " << s2.from << endl;cout << "s2 to: " << s2.to << endl;cout << "s2 ammout: " << s2.amount << endl;}unsigned char data[] = "1234567";//数据unsigned char out[1024] = { 0 };//输出数据unsigned char out2[1024] = { 0 };//1.设置密钥DES_set_key(&key, &key_sch);//数据加密DES_ecb_encrypt((const_DES_cblock*)data, (DES_cblock*)out, &key_sch, DES_ENCRYPT);cout << "加密:" << out << endl;//解密DES_ecb_encrypt((const_DES_cblock*)out, (DES_cblock*)out2, &key_sch, DES_DECRYPT);cout << "解密:" << out2 << endl;getchar();return 0;
}
DES_CBC
void EnSlipCBC(const Slip& s, unsigned char* out, int& out_size)
{int size = sizeof(s);auto p = (const unsigned char*)&s;auto o = out;DES_set_key(&key, &key_sch);DES_cblock iv = { 0 };//初始化向量//初始化向量 DES_cbc_encrypt 调用后值不变    DES_ncbc_encrypt保存上次的值//如果数据不是8的倍数,会自动补0if (size % 8!= 0){out_size = size + (8 - size % 8);}DES_cbc_encrypt(p, o, sizeof(s), &key_sch, &iv,DES_ENCRYPT);
}
void DeSlipCBC(const unsigned char* in, int size, Slip& s)
{DES_cblock iv = { 0 };DES_set_key(&key, &key_sch);//如果补0了,解密后无法知道实际大小,需要用户存储原数据大小DES_cbc_encrypt(in, (unsigned char*)&s, size, &key_sch, &iv, DES_DECRYPT);
}
int main()
{Slip s3;EnSlipCBC(s1, out, out_size);//AttackSlip(out);DeSlipCBC(out, out_size, s3);cout << "s3 from: " << s3.from << endl;cout << "s3 to: " << s3.to << endl;cout << "s3 ammout: " << s3.amount << endl;
}

封装DES实现CBC和ECB的PKCS7Padding分块填充

#pragma once
#include <string>
#include <openssl/des.h>
//枚举类型
enum XSecType
{XDES_ECB,XDES_CBC
};/*
Xsec sec;
sec.Init(XDES_ECB,"12345678",ture);
*/
class  XSec
{
public:/// 初始化加密对象/// <param name="type">加密类型</param>/// <param name="pass">密钥,可以是二进制</param>/// <param name="is_en">true加密,false解密</param>/// 是否成功virtual bool Init(XSecType type, const std::string& pass, bool is_en);/// <summary>/// 加解密数据/// </summary>/// <param name="in">输入数据</param>/// <param name="in_size">数据大小</param>/// <param name="out">输出数据</param>/// <returns>成功返回加解密后数据大小,失败返回0</returns>virtual int Encrypt(const unsigned char* in, int in_size, unsigned char* out);private:/// <summary>///DES_ECB加密模式/// </summary>int EnDesECB(const unsigned char* in, int in_size, unsigned char* out);//DES_ECB解密模式int DeDesECB(const unsigned char* in, int in_size, unsigned char* out);///DES_CBC加密模式/// </summary>int EnDesCBC(const unsigned char* in, int in_size, unsigned char* out);//DES_CBC解密模式int DeDesCBC(const unsigned char* in, int in_size, unsigned char* out);//加密算法密钥DES_key_schedule ks_;//加秘算法类型XSecType type_;bool is_en_;//数据块分组大小int block_size_ = 0;//初始化向量unsigned char iv_[128] = { 0 };
};

#include "xsec.h"
#include <iostream>
using namespace std;bool XSec::Init(XSecType type, const std::string& pass, bool is_en)
{this->type_ = type;this->is_en_ = is_en;this->block_size_ = DES_KEY_SZ;//初始化iv_memset(iv_, 0, sizeof(iv_));const_DES_cblock key = { 0 };//密码策略,超出8字节丢弃,少的补充0int key_size = pass.size();if (key_size > block_size_) key_size = block_size_;memcpy(&key, pass.data(), key_size);DES_set_key(&key, &ks_);return true;
}int XSec::Encrypt(const unsigned char* in, int in_size, unsigned char* out)
{if(type_ == XDES_ECB)if (is_en_){return EnDesECB(in, in_size, out);}else {return DeDesECB(in, in_size, out);}else if (type_ == XDES_CBC)if (is_en_){return EnDesCBC(in, in_size, out);}else {return DeDesCBC(in, in_size, out);}return 0;
}int XSec::EnDesECB(const unsigned char* in, int in_size, unsigned char* out)
{//数据填充PKCS7 Padding//PKCS7Padding:假设数据长度需要填充n(n>0)个字节才对齐,那么填充n个字节,每个字节都是n;如果数据本身就已经对齐了,则填充一块长度为块大小的数据,每个字节都是块大小。unsigned char padding[8] = { 0 };int padding_size = block_size_ - (in_size % block_size_);//填入补充的字节大小memset(padding, padding_size, sizeof(padding));int i = 0;for ( ; i < in_size; i += block_size_){//最后一块数据,小于block_size_ 需要填充if ( in_size-i<block_size_){//填入数据memcpy(padding, in + i, in_size - i);break;}DES_ecb_encrypt((const_DES_cblock*)(in + i), (DES_cblock*)(out + i), &ks_, DES_ENCRYPT);}//补充 PKCS7结尾DES_ecb_encrypt((const_DES_cblock*)padding, (DES_cblock*)(out + i), &ks_, DES_ENCRYPT);return in_size + padding_size;
}int XSec::DeDesECB(const unsigned char* in, int in_size, unsigned char* out)
{for (int i = 0; i < in_size; i += block_size_){DES_ecb_encrypt((const_DES_cblock*)(in + i), (DES_cblock*)(out + i), &ks_, DES_DECRYPT);}return in_size - out[in_size - 1];
}int XSec::EnDesCBC(const unsigned char* in, int in_size, unsigned char* out)
{//数据填充PKCS7 Paddingunsigned char padding[8] = { 0 };int padding_size = block_size_ - (in_size % block_size_);//填入补充的字节大小memset(padding, padding_size, sizeof(padding));//ncbc保留iv修改 减去需要补充的数据DES_ncbc_encrypt(in, out, in_size - (in_size % block_size_),&ks_,(DES_cblock*)iv_,DES_ENCRYPT);//PKCS7 Paddingif (in_size % block_size_ != 0){memcpy(padding, in + (in_size - (in_size % block_size_)), in_size % block_size_);}DES_ncbc_encrypt(padding, out+(in_size - (in_size % block_size_)),sizeof(padding), &ks_, (DES_cblock*)iv_, DES_ENCRYPT);return in_size+padding_size;
}int XSec::DeDesCBC(const unsigned char* in, int in_size, unsigned char* out)
{DES_ncbc_encrypt(in, out, in_size, &ks_, (DES_cblock*)iv_, DES_DECRYPT);return in_size - out[in_size-1];
}int main(int argc, char* argv[])
{{unsigned char data[] = "123456789";unsigned char out[1024] = { 0 };unsigned char out2[1024] = { 0 };XSec sec;//ECB加密sec.Init(XDES_ECB, "12345678", true);cout <<"============== DES_ECB==================" << endl;cout << sizeof(data) << "[" << data << "]" << endl;int size = sec.Encrypt(data, sizeof(data), out);cout << size << ":" << out << endl;//ECB解密sec.Init(XDES_ECB, "12345678", false);size = sec.Encrypt(out, size, out2);cout << size << "[" << out2 << "]" << endl;//CBC解密sec.Init(XDES_CBC, "12345678", true);cout << "============== DES_CBC==================" << endl;cout << sizeof(data) << "[" << data << "]" << endl;size = sec.Encrypt(data, sizeof(data), out);cout << size << ":" << out << endl;//CBC解密sec.Init(XDES_CBC, "12345678", false);size = sec.Encrypt(out, size, out2);cout << size << "[" << out2 << "]" << endl;getchar();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/450987.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第六节——从深层剖析qsort的使用(让你不再害怕指针)

文章目录 1.什么是回调函数2.qsort的使用qsort排序整形数据qsort排序结构体数据qsort排序字符串数据 3.qsort的模拟实现 1.什么是回调函数 回调函数就是⼀个通过函数指针调用的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数传递给另⼀个函数&#xff0c;当…

Python画笔案例-087 绘制 旋转的文字

1、绘制 旋转的文字 通过 python 的turtle 库绘制 旋转的文字,如下图: 2、实现代码 绘制 旋转的文字,以下为实现代码: """旋转的文字.py """ import time from turtle import * from write_patch import *screen = Screen

【JPCS独立出版 | 福州大学主办 | 有确定的ISSN号】第三届可再生能源与电气科技国际学术会议(ICREET 2024)

第三届可再生能源与电气科技国际学术会议&#xff08;ICREET 2024&#xff09; 2024 3rd International Conference on Renewable Energy and Electrical Technology ICREET 2024已成功申请JPCS - Journal of Physics: Conference Series (ISSN:1742-6596) 独立出版&#xf…

架构设计笔记-16-嵌入式系统架构设计理论与实践

目录 知识要点 嵌入式微处理器 存储器&#xff08;memory&#xff09; 内&#xff08;外&#xff09;总线逻辑 嵌入式操作系统&#xff08;Embedded Operating System&#xff0c;EOS&#xff09; 通用中间件 嵌入式中间件的一般架构 典型嵌入式中间件系统 案例分析 1…

搭建mongodb单机部署-认证使用

搭建mongodb单机部署-认证使用 实现思路 先将配置文件配置好&#xff0c;使用不用认证的启动命令启动docker&#xff0c;然后创建账号并制定角色。在使用开启认证的命令重新启动容器就好。 这里我并没有说先停止容器&#xff0c;删掉容器重新创建容器。是因为我的启动命令中…

机器学习—Motivations

学习了线性回归&#xff0c;它预测了一个数字&#xff0c;接下来学习分类&#xff0c;输入变量y只能接收少数几个可能的值中的一个&#xff0c;而不是无限范围内的任何数字。事实证明&#xff0c;线性回归不是分类问题的好算法。这将引入一种不同的算法&#xff0c;叫做Logisti…

立仪科技:光谱共焦传感器精准测量玻璃

光谱共焦测量技术作为一种创新的光学检测方法&#xff0c;近年来在工业领域引起了广泛关注。 它以其高精度、非接触式的特点&#xff0c;特别适用于透明或半透明材料如玻璃的厚度和表面形貌测量。 接下来&#xff0c;立仪科技小编将深入探讨光谱共焦技术在玻璃测量上的应用及其…

【MySQL】增删改查-进阶(一)

目录 &#x1f334;数据库约束 &#x1f6a9;约束类型 &#x1f6a9;NOT NULL &#x1f6a9;UNIQUE &#x1f6a9;DEFAULT &#x1f6a9;PRIMARY KEY &#x1f6a9;FOREIGN KEY &#x1f6a9;CHECK &#x1f384;表的设计 &#x1f6a9;一对一 &#x1f6a9;一对多 …

Spring Boot知识管理:智能搜索与分析

3系统分析 3.1可行性分析 通过对本知识管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本知识管理系统采用JAVA作为开发语言&#xff0c;Spring Boot框…

如何做好SQL 数据库安全

随着信息技术的迅猛发展&#xff0c;数据库在现代信息系统中的重要性日益凸显。无论是电子商务平台、金融系统还是社交媒体应用&#xff0c;数据库都是其核心组件之一。其中&#xff0c;SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;数据库…

微信小程序使用MQTT连接阿里云

目录 一、新建项目和项目整体配置​ 二、MQTT 下载引入和配置连接​ 三、阿里云配置 1、创建产品及设备 2、数据进行云流转 四、创建 MQTT 连接​ 五、微信小程序配置 六、效果展示 1、微信小程序发送控制命令 2、LED台灯反馈LED状态 七、微信小程序项目完整代码 一…

论文笔记:PTR: Prompt Tuning with Rules for Text Classification

Abstract 手动设计大量语言提示麻烦且易出错&#xff0c;而自动生成的提示&#xff0c;在非小样本场景下验证其有效性昂贵且耗时。因此&#xff0c;提示调优以处理多类别分类任务仍然具有挑战。为此&#xff0c;本文提出使用规则进行多类别文本分类提示调优&#xff08;PTR&…

Linux发展与基础

Linux基础知识 Shell 命令执行环境&#xff1a; 命令提示符的组成&#xff1a;(用户名主机名)-[当前路径]权限提示符,例&#xff1a;&#xff08;kali㉿kali)-[~]$ ~ 表示所在目录为家目录:其中root用户的家目录是/root&#xff0c;普通用户的家目录在/home下 # 表示用户的权…

C#学习笔记(二)

C#学习笔记&#xff08;二&#xff09; 第 二 章 命名空间和类、数据类型、变量和代码规范一、命名空间-namespace1. 作用与具体表达形式-using2. 命名空间如何分类&#xff1f;3. 命名空间的命名规范 第 二 章 命名空间和类、数据类型、变量和代码规范 深水区 一、命名空间-…

掌握高效工作汇报技巧:如何利用即时白板打造完美日报,提升职场影响力

在快节奏的工作环境中&#xff0c;撰写工作日报、周报和月报已成为职场人士的日常任务。一份精心准备的工作汇报不仅能够体现我们的敬业精神&#xff0c;还能吸引上级的注意&#xff0c;提升我们在团队中的能见度。使用即时白板作为辅助工具&#xff0c;可以让我们更高效地梳理…

分析调优、性能测试曲线图

目录 一、分析调优 性能测试分析的关键指标 分析步骤 收集数据&#xff1a; 找到瓶颈&#xff1a; 性能调优策略 调优硬件资源&#xff1a; 数据库调优&#xff1a; 持续监控和改进 二、性能测试曲线图 1. 轻负载阶段&#xff08;Light Load&#xff09; 2. 重负载…

mqtt客户端订阅一直重复连接?

文章 前言错误场景问题分析解决方案后言 前言 ✨✨ 他们是天生勇敢的开发者&#xff0c;我们创造bug&#xff0c;传播bug&#xff0c;毫不留情地消灭bug&#xff0c;在这个过程中我们创造了很多bug以供娱乐。 前端bug这里是博主总结的一些前端的bug以及解决方案&#xff0c;感兴…

D37【python 接口自动化学习】- python基础之函数

day37 函数的参数&#xff08;上&#xff09; 学习日期&#xff1a;20241014 学习目标&#xff1a;函数&#xfe63;-50 函数的参数&#xff1a;怎样实现函数与外部数据通信&#xff1f; 学习笔记&#xff1a; 实参与形参 代码实现 # 实参与形参 def foo(number):print(nu…

热更新解决方案2 —— Lua语法相关知识点

概述 开发环境搭建 Lua语法 1.第一个Lua程序 2.变量 print("******变量*******"); --lua当中的简单变量类型 -- nil number string boolean -- lua 中所有的变量声明 都不需要声明变量类型 它会自动的判断类型 -- 类似C# 中的var --lua中的一个变量 可以随便赋值 ——…

Python NumPy 在神经网络中的矩阵运算与激活函数详解

Python NumPy 在神经网络中的矩阵运算与激活函数详解 文章目录 Python NumPy 在神经网络中的矩阵运算与激活函数详解一 矩阵乘法回顾1 定义矩阵2 矩阵乘法计算 二 NumPy 矩阵乘法三 神经网络的分类与回归1 回归问题2 分类问题1&#xff09;定义 sigmoid 函数2&#xff09;定义学…