【常见开源库的二次开发】基于openssl的加密与解密——MD5算法源码解析(五)

一、MD5算法分析 :

1.1 关于MD5

消息摘要”是指MD5(Message Digest Algorithm 5)算法。MD5是一种广泛使用的密码散列函数,它可以生成一个128位(16字节)的散列值。

RFC 1321: MD5由Ronald Rivest在1992年设计,并通过RFC 1321正式发布。它主要用于确保数据完整性,广泛应用于各种软件和系统中,用于验证数据未被篡改

抗碰撞性攻破: 抗碰撞性是指难以找到两个不同的输入值,使它们通过散列函数产生相同的输出值。2004年,中国的密码学家王小云发现了MD5、SHA-0和其他散列函数的碰撞漏洞,这表明MD5对于安全敏感的应用来说已不再安全。

不再安全: 由于MD5的碰撞漏洞,以及随后发现的更多安全弱点,MD5在安全性要求高的领域(如SSL证书、加密货币等)中已逐渐被其他更安全的算法(如SHA-256)所替代。

如果应用加salt: 加盐(salt)是一种安全措施,常用于存储密码。通过向原始密码添加一段随机数据(salt),然后再进行散列,可以增加破解的难度,减少使用彩虹表等攻击技术的风险。然而,即使加盐,由于MD5本身存在的安全漏洞,它仍然不推荐用于需要高安全性的密码存储。

1.2 算法原理

MD5算法将输入的消息分成512位的块,每个块再分成16个32位(4字节)的子块,命名为M0到M15。算法的核心是四轮处理,每轮使用不同的非线性函数(F、G、H、I),每轮包含16次操作,总共64次操作。

以下是MD5算法中四轮处理的概述:

  1. 第一轮:使用函数F,操作如下:

    FF(a, b, c, d, M0, 7, 0xd76aa478); 
    FF(d, a, b, c, M1, 12, 0xe8c7b756); // 继续处理直到M15
  2. 第二轮:使用函数G,操作如下:

    GG(a, b, c, d, M1, 5, 0xf61e2562); 
    GG(d, a, b, c, M6, 9, 0xc040b340); // 继续处理直到M11
  3. 第三轮:使用函数H,操作如下:

    HH(a, b, c, d, M5, 4, 0xfffa3942); 
    HH(d, a, b, c, M8, 11, 0x8771f681); // 继续处理直到M14
  4. 第四轮:使用函数I,操作如下:

    II(a, b, c, d, M0, 6, 0xf4292244);
    II(d, a, b, c, M7, 10, 0x432aff97); // 继续处理直到M15

在每轮中,函数FF、GG、HH、II分别定义了如何更新四个32位的寄存器(a, b, c, d)。这些函数通常包含一个非线性函数(F, G, H, I),一个常数(ac),一个消息块(x),以及一个位移量(s)。

例如,FF函数的定义可能如下:

#define FF(a, b, c, d, x, s, ac) { \ (a) += F((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT((a), (s)); \ (a) += (b); \ }

这里的F是一个非线性函数,ROTATE_LEFT是一个位移操作,将a左移s位,然后加上b

MD5算法的详细实现可以在RFC 1321文档中找到,该文档提供了算法的完整描述和实现细节。然而,由于MD5的安全性问题,现在推荐使用更安全的散列算法,如SHA-256。

二、MD5接口调用

演示如何使用OpenSSL库计算并输出字符串的MD5哈希值,主要用于学习和教学目的。通过这段代码,可以了解MD5哈希算法的基本使用方法,并学习如何使用OpenSSL库的函数来实现这一算法。

源代码:

#include <iostream>
#include <openssl/md5.h>using namespace std;int main() {cout << "Test Hash" << endl; // 输出测试信息unsigned char data[] = "测试MD5数据"; // 定义要进行MD5哈希的数据unsigned char out[MD5_DIGEST_LENGTH] = {0}; // 定义输出数组,大小为MD5哈希结果的长度int len = sizeof(data) - 1; // 计算数据长度,减去1是因为sizeof包含字符串末尾的'\0'MD5_CTX c; // 定义MD5上下文MD5_Init(&c); // 初始化MD5上下文MD5_Update(&c, data, len); // 更新MD5上下文,传入数据和数据长度MD5_Final(out, &c); // 完成MD5哈希,将结果存储在out数组中// 输出MD5哈希结果for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {cout << hex << (int)out[i]; // 以十六进制格式输出每个字节}cout << endl; // 输出换行符,使结果更清晰return 0; // 返回0表示程序成功执行
}

输出测试信息:提示用户程序开始运行。

unsigned char data[] = "测试MD5数据"; // 定义要进行MD5哈希的数据 
unsigned char out[MD5_DIGEST_LENGTH] = {0}; // 定义输出数组,大小为MD5哈希结果的长度 
int len = sizeof(data) - 1; // 计算数据长度,减去1是因为sizeof包含字符串末尾的'\0'

定义输入数据:一个用于计算MD5哈希的字符串。

定义输出数组:存储MD5哈希结果的数组,长度为16字节(MD5_DIGEST_LENGTH)。

计算数据长度sizeof(data) - 1用于获取实际字符串长度,不包括终止符'\0'

MD5_CTX c; // 定义MD5上下文 MD5_Init(&c); // 初始化MD5上下文 
MD5_Update(&c, data, len); // 更新MD5上下文,传入数据和数据长度 
MD5_Final(out, &c); // 完成MD5哈希,将结果存储在out数组中

MD5上下文:使用MD5_CTX结构体来保存MD5计算的中间状态。

初始化MD5上下文:使用MD5_Init函数。

更新MD5上下文:使用MD5_Update函数,将输入数据分块更新到MD5上下文中。

完成MD5哈希:使用MD5_Final函数,将最终的MD5哈希结果存储到输出数组中。

// 输出MD5哈希结果 for (int i = 0; 
i < MD5_DIGEST_LENGTH; i++) 
{ cout << hex << (int)out[i]; // 以十六进制格式输出每个字节 
} 
cout << endl; // 输出换行符,使结果更清晰

输出MD5哈希结果:使用循环遍历输出数组的每个字节,并以十六进制格式输出。

换行符:在输出结束后添加换行符,使输出更整齐。

当我们改变data数组中的某一个值后,我们整个哈希值都会发生改变,修改输入数据的一个字节,然后重新计算该数据的MD5哈希值,并输出结果。通过这种方式,可以观察到数据微小变化对MD5哈希值的影响,从而理解MD5哈希算法的敏感性。

data[1] = 9;
MD5(data,len, out);
for(int i = 0; i < 16; i++)cout << hex << (int)out[i];

三、运用MD5 哈希列表(Hash List)验证文件完整性

哈希列表(Hash List)是一种用于验证文件完整性的技术。通过将文件分割成多个块,并对每个块生成哈希值,然后将所有块的哈希值合并再生成一个总的哈希值,可以有效地验证文件是否在传输或存储过程中被篡改

3.1 读取文件并分块

首先,将文件读取并分割成多个固定大小的块。例如,可以将文件分割成1MB的块。

3.2 生成每个块的哈希值

对每个块生成哈希值。常用的哈希算法包括MD5、SHA-1、SHA-256等。

3.3 合并所有块的哈希值

将所有块的哈希值合并成一个总的哈希值。可以采用类似的方式,将所有块的哈希值拼接起来,然后对这个拼接后的数据生成一个总的哈希值。

3.4 验证文件完整性

在文件传输或存储后,重新执行上述步骤,生成新的哈希列表和总的哈希值。比较新生成的总的哈希值与原始的总的哈希值,如果一致,则文件未被篡改;如果不一致,则文件已被篡改。

3.5 演示代码

通过计算文件的MD5哈希值来监控文件的完整性。如果文件被修改,程序会检测到并输出新的哈希值。

源代码:

#include <iostream>
#include <openssl/md5.h>
#include <fstream>
#include <iomanip>
#include <thread>using namespace std;// 计算文件的MD5哈希值
string GetFileListHash(const string& filepath)
{// 以二进制方式打开文件ifstream ifs(filepath, ios::binary);if (!ifs) {// 如果无法打开文件,输出错误信息并返回空字符串cerr << "Failed to open file: " << filepath << endl;return "";}// 定义一次读取的块大小int block_size = 128;// 定义读取文件的缓冲区unsigned char buf[block_size] = { 0 };// 定义输出哈希的数组unsigned char out[MD5_DIGEST_LENGTH] = { 0 };// 定义并初始化MD5上下文MD5_CTX c;MD5_Init(&c);// 读取文件直至文件末尾while (!ifs.eof()) {ifs.read(reinterpret_cast<char*>(buf), block_size);int read_size = ifs.gcount(); // 获取实际读取的字节数if (read_size > 0) {// 将读取的数据添加到MD5上下文中MD5_Update(&c, buf, read_size);}}// 完成MD5计算并将结果存储在out数组中MD5_Final(out, &c);ifs.close(); // 关闭文件流// 将MD5结果转换为字符串并返回return string(reinterpret_cast<char*>(out), MD5_DIGEST_LENGTH);
}// 以十六进制格式输出数据
void PrintHex(const string& data) {for (unsigned char c : data) {cout << hex << setw(2) << setfill('0') << (int)c;}cout << endl;
}int main() {cout << "Test Hash" << endl; // 输出测试信息unsigned char data[] = "测试MD5数据"; // 定义要进行MD5哈希的数据unsigned char out[MD5_DIGEST_LENGTH] = { 0 }; // 定义输出数组,大小为MD5哈希结果的长度int len = sizeof(data) - 1; // 计算数据长度,减去1是因为sizeof包含字符串末尾的'\0'// 对数据进行MD5哈希计算MD5(data, len, out);// 输出哈希结果for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {cout << hex << setw(2) << setfill('0') << (int)out[i];}cout << endl;data[1] = 9; // 修改数据MD5(data, len, out); // 再次计算MD5哈希for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {cout << hex << setw(2) << setfill('0') << (int)out[i];}cout << endl;string filepath = "/home/book/Desktop/test.txt"; // 文件路径auto hash1 = GetFileListHash(filepath); // 计算文件的哈希值PrintHex(hash1); // 输出文件哈希值// 循环检查文件完整性for (;;) {auto hash = GetFileListHash(filepath); // 重新计算文件哈希值if (hash != hash1) {cout << "文件被修改" << endl;PrintHex(hash); // 输出新的哈希值hash1 = hash; // 更新旧哈希值}this_thread::sleep_for(1s); // 每秒检查一次}return 0; // 程序正常结束
}

新建一个txt文件作为存储文件:

文件所形成的哈希值:

当我们改变txt文件中的内容后不断输出文件被修改并且输出修改后文件的哈希值:

函数 GetFileListHash 用于计算指定文件的MD5哈希值。

以二进制模式打开文件。

定义缓冲区 buf 用于读取文件内容。

初始化 MD5 上下文 MD5_CTX

循环读取文件内容并更新 MD5 上下文。

完成 MD5 计算并返回哈希值。

函数 PrintHex 将数据以十六进制格式输出。

遍历输入数据的每个字节。

使用 hexsetw(2) 和 setfill('0') 格式化输出。

初始化并测试 MD5 哈希计算

定义一个字符串 data 进行MD5哈希计算。

输出初始字符串的 MD5 哈希值。

修改字符串 data 并再次计算其 MD5 哈希值。

文件哈希计算与监控

指定文件路径 filepath

计算文件的初始 MD5 哈希值 hash1 并输出。

进入无限循环,不断重新计算文件的 MD5 哈希值,并与初始哈希值进行比较。

如果哈希值发生变化,输出新的哈希值,并更新初始哈希值 hash1

每秒钟检查一次文件的哈希值。

通过计算文件的 MD5 哈希值来监控文件的完整性。它首先进行字符串的 MD5 哈希计算以测试功能,然后进入一个无限循环,定期检查指定文件的 MD5 哈希值。如果检测到文件发生了变化,程序会输出新的哈希值并更新记录的哈希值。

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

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

相关文章

算法017:二分查找

二分查找. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/binary-search/ 二分查找&#xff0c;其实是双指针的一种特殊情况&#xff0c;但是时间复杂度极低&#…

Web前端:HTML篇(一)

HTML简介&#xff1a; 超文本标记语言&#xff08;英语&#xff1a;HyperText Markup Language&#xff0c;简称&#xff1a;HTML&#xff09;是一种用于创建网页的标准标记语言。 您可以使用 HTML 来建立自己的 WEB 站点&#xff0c;HTML 运行在浏览器上&#xff0c;由浏览器…

MongoDB教程(十三):MongoDB覆盖索引

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言什么是覆盖…

Elasticsearch介绍、安装以及IK分词器 --学习笔记

Elasticsearch 是什么&#xff1f; Elasticsearch 是一个高度可扩展的开源全文搜索和分析引擎。它允许你以极快的速度存储、搜索和分析大量数据。Elasticsearch 基于 Apache Lucene 构建&#xff0c;提供了一个分布式、多租户能力的全文搜索引擎&#xff0c;带有 HTTP web 接口…

安装Ubuntu24.04服务器版本

Ubuntu系统安装 一.启动安装程序二.执行 Ubuntu Server 安装向导1.选择安装程序语言&#xff0c;通常选择「English」2.设置键盘布局&#xff0c;默认「English US」即可3.选择安装方式 三.配置网络1.按Tab键选择网络接口&#xff08;例如 ens160&#xff09;&#xff0c;然后按…

Java:115-Spring Boot的底层原理(下篇)

这里续写上一章博客&#xff08;115章博客&#xff09; SpringBoot视图技术&#xff1a; 支持的视图技术 &#xff1a; 前端模板引擎技术的出现&#xff08;jsp也是&#xff09;&#xff0c;使前端开发人员无需关注后端业务的具体实现&#xff08;jsp中&#xff0c;具体的…

[Doris]阿里云搭建Doris,测试环境1FE 1BE

首先&#xff1a;阿里云的国内服务器千万不要用容器搭建&#xff0c;或者自己Dockfile构建镜像。两种方式都不得行&#xff0c;压根拉不到github的镜像&#xff0c;开了镜像加速器也拉不到&#xff0c;不要折腾了&#xff0c;极其愚蠢。 背景&#xff1a;现在测试环境&#xff…

openmv学习笔记(24电赛备赛笔记)

#openmv简介 openmv一种小型&#xff0c;可编程机器视觉摄像头&#xff0c;设计应用嵌入式应用和计算边缘&#xff0c;是图传模块&#xff0c;或者认为是一种&#xff0c;具有图像处理功能的单片机&#xff0c;提供多种接口&#xff08;I2C SPI UART CAN ADC DAC &#xff0…

Linux云计算 |【第一阶段】ENGINEER-DAY4

主要内容&#xff1a; 配置Linux网络参数、配置静态主机名、查看/修改/激活/禁用网络连接、指定DNS、虚拟网络连接、虚拟机克隆、SSH客户端、SCP远程复制、SSH无密码验证&#xff08;SERVICE-DAY5&#xff09;、虚拟网络类型 一、网络参数配置 修改网卡配置文件主要是需要配置…

人工智能与社交变革:探索Facebook如何领导智能化社交平台

在过去十年中&#xff0c;人工智能&#xff08;AI&#xff09;技术迅猛发展&#xff0c;彻底改变了我们与数字世界互动的方式。Facebook作为全球最大的社交媒体平台之一&#xff0c;充分利用AI技术&#xff0c;不断推动社交平台的智能化&#xff0c;提升用户体验。本文将深入探…

资源调度的艺术:大规模爬虫管理的优化策略

摘要 本文深入探讨了在处理大规模数据抓取项目时&#xff0c;如何通过优化资源调度策略来提升爬虫管理的效率与稳定性。从技术选型到策略实施&#xff0c;揭示了优化的核心技巧&#xff0c;助力企业与开发者高效驾驭大数据采集的挑战。 正文 在互联网信息爆炸的时代&#xf…

TypeScript 开发或面试中常见问题合集

目录 typescript 与 babel 区别编译编译器 模块模块解析规则 命名空间interface 合并逻辑声明合并 普通项目怎么从 js 迁移到 ts解决冲突 第三方工具生成.d.ts文件三斜线指令模块解析逻辑types 发布书写 ts 的声明文件Property includes does not exist on type number[] globa…

RSA非对称加密

前言 RSA是一种非对称加密算法&#xff0c;也是目前最常用的加密算法之一。它由三位发明家&#xff08;Rivest、Shamir、Adleman&#xff09;于1977年提出&#xff0c;并以他们的姓氏命名。RSA算法使用了两个密钥&#xff1a;公钥和私钥。公钥可用于对数据进行加密&#xff0c…

《Exploring Aligned Complementary Image Pair for Blind Motion Deblurring》

这篇论文的标题《Exploring Aligned Complementary Image Pair for Blind Motion Deblurring》可以翻译为《探索对齐的互补图像对用于盲运动去模糊》。从标题可以推断,论文的焦点在于开发一种算法或技术,利用成对的图像来解决运动模糊问题,特别是在不知道模糊核(即造成模糊…

第一弹:基于ABAP OLE技术实现对服务器文件进行读写操作

前言 最近遇到这样一个需求&#xff0c;需要对BW服务器上的文件进行下载的同时写入每个用户相对应的数据。之前的服务器模版是一个死模版&#xff0c;对于这样的要求&#xff0c;我就想到了OLE技术&#xff0c;那么什么是OLE技术呢&#xff1f; 一、什么是OLE技术&#xff1f…

Modbus转BACnet/IP网关快速对接Modbus协议设备与BA系统

摘要 在智能建筑和工业自动化领域&#xff0c;Modbus和BACnet/IP协议的集成应用越来越普遍。BA&#xff08;Building Automation&#xff0c;楼宇自动化&#xff09;系统作为现代建筑的核心&#xff0c;需要高效地处理来自不同协议的设备数据&#xff0c;负责监控和管理建筑内…

深入浅出mediasoup—通信框架

libuv 是一个跨平台的异步事件驱动库&#xff0c;用于构建高性能和可扩展的网络应用程序。mediasoup 基于 libuv 构建了包括管道、信号和 socket 在内的一整套通信框架&#xff0c;具有单线程、事件驱动和异步的典型特征&#xff0c;是构建高性能 WebRTC 流媒体服务器的重要基础…

使用 spring MVC 简单的案例 (1)计算器

一、计算器 1.1前端代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> …

Git报错fatal: detected dubious ownership in repository

报错信息 fatal: detected dubious ownership in repository at 解决办法 一行代码解决 git config --global --add safe.directory "*";如何使用git工具初始胡项目并且和远程仓库建立联系 git init–建立一个本地仓库 git add README.md–将README.md文件加入…

MySQL添加索引时会锁表吗?

目录 简介Online DDL概念Online DDL用法总结 简介 在MySQL5.5以及之前的版本&#xff0c;通常更改数据表结构操作&#xff08;DDL&#xff09;会阻塞对表数据的增删改操作&#xff08;DML&#xff09;。 MySQL5.6提供Online DDL之后可支持DDL与DML操作同时执行&#xff0c;降低…