【Linux】C语言实现对文件的加密算法

异或加密

解密方式是进行第二次加密后自动解密

#define BUF_SIZE (16384)    //16k
/**************************************************************
功能描述: 加密实现
输入参数: 
---------------------------------------------------------------
修改作者: 
修改日期: 
修改说明:新增
***************************************************************/
void log_encrypt(char *data, int dataLen, const char *key)
{int n = 0;//对data的每一个字符和key进行按位异或for(n = 0; n < dataLen; n++){*data = *data ^ 0x09;data++;}
}/**************************************************************
功能描述: log文件加密
输入参数: 
---------------------------------------------------------------
修改作者: 
修改日期: 
修改说明:新增
***************************************************************/
unsigned int log_encryptFile(char *srcFileName)
{char *key = "google";int  srcFd = -1;int  dstFd = -1;char *tmpBuf = NULL;int  tmpLen = 0;int  writLen = 0;log_printf("start: CountFile build date: %s, [%s, %d]\n", __DATE__, __FUNCTION__, __LINE__);if (!srcFileName){log_printf("srcFileName err![%s, %d]\n", __FUNCTION__, __LINE__);return EXIT_FAILURE;}srcFd = open(srcFileName, O_RDWR);log_printf("srcFileName:[%s] fd:[%d]\n", srcFileName, srcFd);if (srcFd < 0){log_printf("open src file failed! [err:%d:%s]\n", errno, strerror(errno));return EXIT_FAILURE;}log_printf("file size:[%d]\n", lseek(srcFd, 0, SEEK_END));lseek(srcFd, 0, SEEK_SET);tmpBuf = (char *)malloc(BUF_SIZE);if (!tmpBuf){log_printf("malloc buf failed! [err:%d:%s]\n", errno, strerror(errno));close(srcFd);return EXIT_FAILURE;}while((tmpLen = read(srcFd, tmpBuf, BUF_SIZE)) > 0){//加密数据log_encrypt(tmpBuf, tmpLen, key);//指针会到此包开始处lseek(srcFd, -tmpLen, SEEK_CUR);//写文件writLen = write(srcFd, tmpBuf, tmpLen);if (writLen < 0){log_printf("write err,Error: %s\n", strerror(errno));}}close(srcFd);free(tmpBuf);log_printf("end: ok: [%s, %d]\n", __FUNCTION__, __LINE__);return EXIT_SUCCESS;
}

AES加密

AES的算法时间复杂度最低,256K时间如下:
在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/sha.h>#define BLOCK_SIZE 16
#define KEY_BIT 256
#define IV_SIZE BLOCK_SIZE
#define KEY_SIZE (KEY_BIT/8)
#define JIEMI_SWITCH		1	//解密开关
// Generate IV
unsigned char iv[IV_SIZE] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};void file_encrypt(char* filename) {FILE* fp = fopen(filename, "rb");FILE* outfp = fopen("encrypted.tmp", "wb");if(fp == NULL) {printf("Can't open file.\n");return;}// Generate keyunsigned char key[KEY_SIZE];SHA256((unsigned char*)"google", strlen("google"), key);EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();if(EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv) != 1) {printf("Failed to initialize encryption.\n");return;}unsigned char data_block[BLOCK_SIZE];unsigned char encrypt_block[BLOCK_SIZE + EVP_MAX_BLOCK_LENGTH];int out_len;fseek(fp, 0, SEEK_END);long file_size = ftell(fp);fseek(fp, 0, SEEK_SET);unsigned char* buffer = (unsigned char*)malloc(file_size + EVP_MAX_BLOCK_LENGTH);fread(buffer, 1, file_size, fp);for(long i = 0; i < file_size; i += BLOCK_SIZE) {memcpy(data_block, buffer + i, BLOCK_SIZE);if(i + BLOCK_SIZE > file_size) {for(int j = file_size % BLOCK_SIZE; j < BLOCK_SIZE; ++j)data_block[j] = BLOCK_SIZE - (file_size % BLOCK_SIZE);}if(EVP_EncryptUpdate(ctx, encrypt_block, &out_len, data_block, BLOCK_SIZE) != 1) {printf("Failed to encrypt block.\n");return;}fwrite(encrypt_block, 1, out_len, outfp);}if(EVP_EncryptFinal_ex(ctx, encrypt_block, &out_len) != 1) {printf("Failed to finish encryption.\n");return;}fwrite(encrypt_block, 1, out_len, outfp);free(buffer);fclose(fp);fclose(outfp);rename("encrypted.tmp", filename);EVP_CIPHER_CTX_free(ctx);
}void file_decrypt(char* filename) {FILE* fp = fopen(filename, "rb");FILE* outfp = fopen("decrypted.tmp", "wb");if(fp == NULL) {printf("Can't open file.\n");return;}// Generate keyunsigned char key[KEY_SIZE];SHA256((unsigned char*)"google", strlen("google"), key);EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();if(EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv) != 1) {printf("Failed to initialize decryption.\n");return;}unsigned char data_block[BLOCK_SIZE];unsigned char decrypt_block[BLOCK_SIZE + EVP_MAX_BLOCK_LENGTH];int out_len;fseek(fp, 0, SEEK_END);long file_size = ftell(fp);fseek(fp, 0, SEEK_SET);unsigned char* buffer = (unsigned char*)malloc(file_size + EVP_MAX_BLOCK_LENGTH);fread(buffer, 1, file_size, fp);for(long i = 0; i < file_size; i += BLOCK_SIZE) {memcpy(data_block, buffer + i, BLOCK_SIZE);if(EVP_DecryptUpdate(ctx, decrypt_block, &out_len, data_block, BLOCK_SIZE) != 1) {printf("Failed to decrypt block.\n");return;}fwrite(decrypt_block, 1, out_len, outfp);}if(EVP_DecryptFinal_ex(ctx, decrypt_block, &out_len) != 1) {printf("Failed to finish decryption.\n");return;}fwrite(decrypt_block, 1, out_len, outfp);free(buffer);fclose(fp);fclose(outfp);rename("decrypted.tmp", filename);EVP_CIPHER_CTX_free(ctx);
}int main(int argc, char **argv) {if(argc != 2) {printf("Usage: %s <file>\n", argv[0]);return 1;}char *srcFileName = argv[1];
#if JIEMI_SWITCHfile_encrypt(srcFileName);printf("加密成功\n");
#elsefile_decrypt(srcFileName);printf("解密成功\n");
#endifreturn 0;
}

简单加密

它只是对输入文件进行简单的异或加密操作,使用一个字符串作为密钥
时间复杂度较高,对257K的文件加密,要33s
在这里插入图片描述

/**************************************************************
修改作者:wangjj
修改日期:9/25/2023
修改说明:新增
***************************************************************/
unsigned int log_encryptFile(char *srcFileName)
{char *key = "hualaixiaofang";int keyLen = strlen(key);int ch;int i = 0;log_printf("encrytFile begin [%s,%d\n]", __FUNCTION__, __LINE__);if (!srcFileName || !key){log_printf("param err! error:%s [%s,%d]\n", strerror(errno), __FUNCTION__, __LINE__);return EXIT_FAILURE;}	FILE *file = fopen(srcFileName, "rb+");if (file == NULL){log_printf("open file failed!!, error:%s [%s,%d]\n", strerror(errno), __FUNCTION__, __LINE__);return EXIT_FAILURE;}while ((ch = fgetc(file)) != EOF){// 对每个字符和key的对应字符进行加密操作ch = ch + key[i];// 将加密后的字符写回文件fseek(file, -1, SEEK_CUR);fputc(ch, file);// 更新key的位置i = (i + 1) % keyLen;}log_printf("encrytFile end [%s,%d\n]", __FUNCTION__, __LINE__);fclose(file);
}

编译方式

gcc -o decrypt_program_jiemi AES_encrypt.c -lcrypto

mbedtls加密


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mbedtls/aes.h"#define KEY_SIZE 32 // 256位密钥
#define BLOCK_SIZE 16 // 128位分组int log_encryptFile(const char* input_file) {// 打开输入文件FILE* input = fopen(input_file, "rb");if (input == NULL) {printf("无法打开输入文件\n");return -1;}const unsigned char key[KEY_SIZE] = "wjj";// 计算输入文件大小fseek(input, 0, SEEK_END);long input_size = ftell(input);fseek(input, 0, SEEK_SET);// 创建输出缓冲区unsigned char* output = (unsigned char*)malloc(input_size);if (output == NULL) {printf("内存分配失败\n");fclose(input);return -1;}// 初始化加密上下文mbedtls_aes_context ctx;mbedtls_aes_init(&ctx);mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE * 8);// 加密文件内容unsigned char input_block[BLOCK_SIZE];unsigned char output_block[BLOCK_SIZE];size_t offset = 0;size_t read_bytes;while ((read_bytes = fread(input_block, 1, BLOCK_SIZE, input)) > 0) {mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, input_block, output_block);memcpy(output + offset, output_block, read_bytes);offset += read_bytes;}// 关闭文件和释放资源fclose(input);mbedtls_aes_free(&ctx);// 打开输入文件,以写入方式覆盖原内容input = fopen(input_file, "wb");if (input == NULL) {printf("无法打开输入文件\n");free(output);return -1;}// 将加密后的内容写入输入文件fwrite(output, 1, input_size, input);// 关闭文件和释放资源fclose(input);free(output);printf("文件加密完成\n");return 0;
}int log_decryptFile(const char* input_file) {// 打开输入文件FILE* input = fopen(input_file, "rb");if (input == NULL) {printf("无法打开输入文件\n");return -1;}const unsigned char key[KEY_SIZE] = "wjj";// 计算输入文件大小fseek(input, 0, SEEK_END);long input_size = ftell(input);fseek(input, 0, SEEK_SET);// 创建输出缓冲区unsigned char* output = (unsigned char*)malloc(input_size);if (output == NULL) {printf("内存分配失败\n");fclose(input);return -1;}// 初始化解密上下文mbedtls_aes_context ctx;mbedtls_aes_init(&ctx);mbedtls_aes_setkey_dec(&ctx, key, KEY_SIZE * 8);// 解密文件内容unsigned char input_block[BLOCK_SIZE];unsigned char output_block[BLOCK_SIZE];size_t offset = 0;size_t read_bytes;while ((read_bytes = fread(input_block, 1, BLOCK_SIZE, input)) > 0) {mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, input_block, output_block);memcpy(output + offset, output_block, read_bytes);offset += read_bytes;}// 关闭文件和释放资源fclose(input);mbedtls_aes_free(&ctx);// 打开输入文件,以写入方式覆盖原内容input = fopen(input_file, "wb");if (input == NULL) {printf("无法打开输入文件\n");free(output);return -1;}// 将解密后的内容写入输入文件fwrite(output, 1, input_size, input);// 关闭文件和释放资源fclose(input);free(output);printf("文件解密完成\n");return 0;
}
// 编译方式:gcc -o decrypt-jiami AES_encrypt.c -lmbedtls -lmbedcrypto -lmbedx509
int main(int argc, char **argv) {if(argc != 2) {printf("Usage: %s <file>\n", argv[0]);return 1;}char *srcFileName = argv[1];if (log_encryptFile(srcFileName) != 0) {printf("加密文件失败\n");return -1;}printf("文件加密完成\n");#if 0if (log_decryptFile(srcFileName) != 0) {printf("解密文件失败\n");return -1;}printf("解密成功\n");
#endif return 0;
}

编译方式

gcc -o decrypt-jiami AES_encrypt.c -lmbedtls -lmbedcrypto -lmbedx509

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

山西电力市场日前价格预测【2023-09-27】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-09-27&#xff09;山西电力市场全天平均日前电价为342.48元/MWh。其中&#xff0c;最高日前电价为454.24元/MWh&#xff0c;预计出现在18: 30。最低日前电价为171.32元/MWh&#xff0c;预计…

如何永久关闭WPS任务窗口?

1、按住任务窗口上的浮动按钮&#xff0c;将其拖出来成悬浮窗口。 第二步&#xff0c;使用火绒弹窗拦截&#xff0c;选中弹出的窗口&#xff0c;进行拦截。注意&#xff1a;拦截次数为2次。即进行2次操作。 操作两次后&#xff0c;弹窗被拦截&#xff0c;此时Word文档改为双页显…

蓝桥杯每日一题20223.9.26

4407. 扫雷 - AcWing题库 题目描述 分析 此题目使用map等都会超时&#xff0c;所以我们可以巧妙的使用哈希模拟散列表&#xff0c;哈希表初始化为-1首先将地雷读入哈希表&#xff0c;找到地雷的坐标在哈希表中对应的下标&#xff0c;如果没有则此地雷的位置第一次出现&#…

QQ怎么上传大于1G的视频啊?视频压缩这样做

当我们想要在QQ上分享一段大容量的视频时&#xff0c;往往会因为超过1G的限制而感到无助。不过&#xff0c;不用担心&#xff0c;今天我们将为你介绍三种可以压缩视频大小的方法&#xff0c;一起来看看吧~ 一、嗨格式压缩大师 嗨格式压缩大师是一款专业的视频压缩软件&#xf…

全渠道客服体验:Rocket.Chat 的无缝互动 | 开源日报 No.41

RocketChat/Rocket.Chat Stars: 36.9k License: NOASSERTION Rocket.Chat 是一个完全可定制的开源通信平台&#xff0c;适用于具有高标准数据保护要求的组织。我们是团队沟通场景下的最终免费开源解决方案&#xff0c;可以实现同事之间、公司之间或客户之间的实时对话。提高生…

13. ShardingSphere-Proxy 数据库代理

Spring Cloud 微服务系列文章&#xff0c;点击上方合集↑ 1. 简介 ShardingSphere-Proxy是ShardingSphere分布式数据库中间件的一部分&#xff0c;它提供了数据库代理功能。通过引入ShardingSphere-Proxy&#xff0c;可以在无需改动应用程序代码的情况下&#xff0c;实现分库…

使用Process Monitor工具探测日志文件是程序哪个模块生成的

目录 1、问题描述 2、使用Process Monitor监测目标文件是哪个模块生成的思路说明 3、操作Process Monitor监测日志文件是哪个模块生成的 4、通过screenctach.dll库的时间戳&#xff0c;找到其pdb文件&#xff0c;然后去查看详细的函数调用堆栈 5、最后 VC常用功能开发汇总…

用智能文字识别技术赋能古彝文数字化之路

目录 1、前言 2、对古彝文古籍的保护迫在眉睫 3、古彝文识别的难点问题 4、古彝文文字识别的关键技术 4.1、智能高清滤镜技术 4.2、图像矫正 4.3、图像增强 4.4、版面还原 5、合合信息识别技术赋能古彝文数字化 1、前言 古彝文指的是在云南、贵州、四川等地的彝族人之…

uniapp 可输入可选择的........框

安装 uniapp: uni-combox地址 vue页面 <uni-combox :border"false" input"selectname" focus"handleFocus" blur"handleBlur" :candidates"candidates" placeholder"请选择姓名" v-model"name"&g…

yolov5及yolov7实战之剪枝

之前有讲过一次yolov5的剪枝&#xff1a;yolov5实战之模型剪枝_yolov5模型剪枝-CSDN博客 当时基于的是比较老的yolov5版本&#xff0c;剪枝对整个训练代码的改动也比较多。最近发现一个比较好用的剪枝库&#xff0c;可以在不怎么改动原有训练代码的情况下&#xff0c;实现剪枝的…

使用自定义注解发布webservice服务

使用自定义注解发布webservice服务 概要代码自定义注解WebService接口服务发布配置使用 结果 概要 在springboot使用webservice&#xff0c;发布webservice服务的时候&#xff0c;我们经常需要手动在添加一些发布的代码&#xff0c;比如&#xff1a; Bean public Endpoint or…

破信息壁垒,亿发一站式ERP系统建设,打造五金制造信息管理平台

五金制造拥有明显的行业特征&#xff0c;如体量小、品种繁多、颜色多样、加工工艺不断演进等&#xff0c;呈现出一种独特的管理挑战。大多数五金企业仍然依赖人工管理和经验决策&#xff0c;如今需要寻求更合理和科学的决策方法&#xff0c;以实现生产、销售、仓储、采购和财务…

百度SEO优化技巧(选择、网站结构、内容优化、外链建设、数据分析)

百度关键词SEO优化介绍 SEO是搜索引擎优化的缩写&#xff0c;是指通过优化网站结构、内容和外部链接等方式&#xff0c;提高网站在搜索引擎中的排名&#xff0c;从而获取更多的访问量和流量。百度是中国最大的搜索引擎之一&#xff0c;对于企业来说&#xff0c;优化百度关键词…

uniapp 事件委托失败 获取不到dataset

问题&#xff1a; v-for 多个span ,绑定点击事件 代码:view里包着一个span, <view class"status-list" tap"search"><span class"status-item" v-for"(key,index) in statusList" :key"index" :data-key"k…

USB转换方案介绍

随着科技的不断发展&#xff0c;我们的生活中出现了越来越多的电子设备。然而&#xff0c;这些设备通常具有不同的连接端口和协议&#xff0c;这可能会使它们之间的连接变得困难。这时候&#xff0c;使用USB转换就成为了一种非常方便和实用的解决方法。 无论是在家庭、办公室还…

系统集成|第十章(笔记)

目录 第十章 质量管理10.1 项目质量管理概论10.2 主要过程10.2.1 规划质量管理10.2.2 实施质量保证10.2.3 质量控制 10.3 常见问题 上篇&#xff1a;第九章、成本管理 下篇&#xff1a;第十一章、人力资源管理 第十章 质量管理 10.1 项目质量管理概论 质量管理&#xff1a;指确…

创建型设计模式——工厂模式

摘要 本博文主要介绍软件设计模式中工厂模式&#xff0c;其中工厂设计模式的扩展为简单工厂(Simple Factory)、工厂方法(Factory Method)、抽象工厂(Abstract Factory)三种。 一、简单工厂(Simple Factory) 主要分析设计模式 - 简单工厂(Simple Factory)&#xff0c;它把实例…

PHP8的类与对象的基本操作之类的实例化-PHP8知识详解

定义完类和方法后&#xff0c;并不是真正创建一个对象。类和对象可以描述为如下关系。类用来描述具有相同数据结构和特征的“一组对象”&#xff0c;“类”是“对象”的抽象&#xff0c;而“对象”是“类”的具体实例&#xff0c;即一个类中的对象具有相同的“型”&#xff0c;…

【DETR】

https://tianfeng.space/ 前言 论文 代码 DETR&#xff08;Data-efficient Image Transformer&#xff09;是一种用于目标检测任务的深度学习模型。它与传统的目标检测方法不同&#xff0c;采用了Transformer架构&#xff0c;将目标检测问题转化为一个序列到序列的问题。以下…

Java之IO流概述

1.1 什么是IO 生活中&#xff0c;你肯定经历过这样的场景。当你编辑一个文本文件&#xff0c;忘记了ctrls &#xff0c;可能文件就白白编辑了。当你电脑上插入一个U盘&#xff0c;可以把一个视频&#xff0c;拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢&#xff1f;键…