MD5加密原理解析及OC版原理实现

本文涉及的产品
云解析DNS-重点域名监控,免费拨测 20万次(价值200元)
简介: MD5加密原理解析及OC版原理实现

一、MD5算法基础概念


     MD5算法是Hash算法的一种,叫做讯息摘要演算法。所谓摘要,从字面意思理解,是指内容的大概。在MD5算法中,这个摘要是指将任意数据映射成一个128位长的摘要信息。并且其是不可逆的,即从摘要信息无法反向推演中原文,在演算过程中,原文的内容也是有丢失的。


     因为MD5算法最终生成的是一个128位长的数据,从原理上说,有2^128种可能,这是一个非常巨大的数据,约等于3.4乘10的38次方,虽然这个是个天文数字,但是世界上可以进行加密的数据原则上说是无限的,因此是可能存在不同的内容经过MD5加密后得到同样的摘要信息,但这个碰中的概率非常小。


二、MD5的使用场景


     MD5常用在密码加密中,一般为了保证用户密码的安全,在数据库中存储的都是用户的密码经过MD5加密后的值,在客户端用户输入密码后,也会使用MD5进行加密,这样即使用户的网络被窃听,窃听者依然无法拿到用户的原始密码,并且即使用户数据库被盗,没有存储明文的密码对用户来说也多了一层安全保障。


     MD5签名技术还常用于防止信息的篡改。使用MD5可以对信息进行签名,接收者拿到信息后只要重新计算签名和原始签名进行对比,即可知道数据信息是否中途被篡改了。


三、MD5算法原理


     MD5算法大致分为4步完成:


第1步:进行数据填充整理


     这一步是对要加密的数据进行填充和整理,将要加密的二进制数据对512取模,得到的结果如果不够448位,则进行补足,补足的方式是第1位填充1,后面全部填充0。


第2步:记录数据长度


    经过第一步整理完成后的数据的位数可以表示为N*512+448,再向其后追加64位用来存储数据的长度,比如数据的长度为16字节,则用10000来填充后64位。这一步做完后,数据的位数将变成(N+1)*512。


第3步:以标准的幻数作为输入


   MD5的实现需要每512个字节进行一次处理,后一次处理的输入为前一次处理的输出,因此,在循环处理开始之前,需要拿4个标准数作为输入,它们分别是:


unsigned int A=0x67452301,B=0xefcdab89,C=0x98badcfe,D=0x10325476;

第4步:进行N轮循环处理,将最后的结果输出


   这一步重要的是每一轮的处理算法,每一轮处理也要循环64次,这64次循环被分为4各组,每16次循环为一组,每组循环使用不同的逻辑处理函数,处理完成后,将输出作为输入进入下一轮循环。


四、MD5核心算法的实现


  这里演示的是每轮循环的核心算法:


首先进行3个函数的声明:


//将大端字节序转换为小端字节序

void convertToLittleEndian(unsigned int *data, int len);

//进行循环左移函数

void ROL(unsigned int *s, unsigned short cx);

//MD5加密函数

void MD5(NSString *str);

MD5算法中处理的数据都是小端字节序的,而使用Objective-C处理的NSData对象的字节序是大端字节序,因此我们需要做一下转换。函数实现如下:


void convertToLittleEndian(unsigned int *data, int len)

{

   for (int index = 0; index < len; index ++) {

     

       *data = ((*data & 0xff000000) >> 24)

       | ((*data & 0x00ff0000) >>  8)

       | ((*data & 0x0000ff00) <<  8)

       | ((*data & 0x000000ff) << 24);

     

       data ++;

   }

}

在MD5中有需要对字节数据进行循环左移的操作,循环左移函数实现如下:


void ROL(unsigned int *s, unsigned short cx)

{

   if (cx > 32)cx %= 32;

   *s = (*s << cx) | (*s >> (32 - cx));

  return;

}

下面是MD5函数的核心实现:


void MD5(NSString *str){

   const void * bytes[str.length];

   //字符串转字节流

   [str getBytes:bytes maxLength:str.length usedLength:nil encoding:NSUTF8StringEncoding options:NSStringEncodingConversionExternalRepresentation range:NSMakeRange(0, str.length) remainingRange:nil];

   //使用NSData存储

   NSMutableData * data = [[NSMutableData alloc] initWithBytes:bytes length:str.length];

   BOOL first = YES;

   //进行数据填充

   if (data.length<56) {

       do {

           if (first) {

               int byte = 0b10000000;

               [data appendBytes:&byte length:1];

               first = NO;

           }else{

               int byte = 0b00000000;

               [data appendBytes:&byte length:1];

           }

       } while (data.length<56);

   }

   int length = (int)str.length*8%((int)pow(2, 64));

   [data appendBytes:&length length:8];

   void * newBytes[64];

   memcpy(newBytes, [data bytes], 64);

   //大小端转换

   convertToLittleEndian(newBytes, 64);

   NSData * newData = [NSData dataWithBytes:newBytes length:data.length];

   NSMutableArray * subData = [NSMutableArray array];

   //进行分组

   for (int i = 0; i<16; i++) {

       [subData addObject: [newData subdataWithRange:NSMakeRange(i*4, 4)]];

   }

   //初始输入

   unsigned int A=0x67452301,B=0xefcdab89,C=0x98badcfe,D=0x10325476;

   unsigned int a=A,b=B,c=C,d=D;

   unsigned int s[64] = { 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11,16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15,21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 };

   unsigned int  k[64] = {

       0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,

       0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,

       0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,

       0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,

       0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,

       0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,

       0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,

       0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,

       0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,

       0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,

       0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,

       0xd9d4d039,  0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,

       0xf4292244, 0x432aff97,  0xab9423a7, 0xfc93a039,

       0x655b59c3, 0x8f0ccc92, 0xffeff47d,  0x85845dd1,

       0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,

       0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };

 

   //64次循环处理

   for (int i = 0; i <= 64; i++) {

     

       if (i<64) {

           unsigned int f;

           unsigned int g;

           if (i<16) {  

               f = (b&c)|((~b)&d);

               g = i;

           }else if(i<32) {

               f = (b&d)|((~d)&c);

               g = (5*i+1)%16;

           }else if(i<48){

               f = b^c^d;

               g = (3*i+5)%16;

           }else{

               f = c^((~d)|b);

               g = (7*i)%16;

           }

           unsigned int * temp = (unsigned int *) [subData[g] bytes];

           unsigned int  *tem = malloc(sizeof(unsigned int));

           memcpy(tem, temp, 4);

           convertToLittleEndian(tem, 4);

           unsigned int res = (a+f+*tem+k[i]);

           ROL(&res,s[i]);

           unsigned int t = res+b;

           a = d;

           d = c;

           c = b;

           b = t;

       

       }else{

           A = a+A;

           B = b+B;

           C = c+C;

           D = d+D;

       }

   }

   //大小端转换

   unsigned int * newA = malloc(sizeof(unsigned int));

   memcpy(newA, &A, 4);

   NSLog(@"%0x",*newA);

   convertToLittleEndian(newA, 4);

   unsigned int * newB = malloc(sizeof(unsigned int));

   memcpy(newB, &B, 4);

   convertToLittleEndian(newB, 4);

   unsigned int * newC = malloc(sizeof(unsigned int));

   memcpy(newC, &C, 4);

   convertToLittleEndian(newC, 4);

   unsigned int * newD = malloc(sizeof(unsigned int));

   memcpy(newD, &D, 4);

   convertToLittleEndian(newD, 4);

   NSLog(@"AAA:%0x %0x %0x %0x ",*newA,*newB,*newC,*newD);

}

 

目录
相关文章
|
6月前
|
存储 安全 算法
用 MD5 加密 WordPress 验证码的完整教程
本文详细介绍了如何使用MD5加密技术增强WordPress验证码的安全性。通过将验证码答案以MD5形式加密并存储在Session中,避免了明文传输可能带来的安全风险。文章从形势分析、MD5算法介绍到实战操作步骤,逐步引导读者实现加密验证流程。同时提供了调试方法,确保修改生效。此教程旨在为网站添加一层安全保障,提升对抗网络攻击的能力。
353 1
|
7月前
|
存储 算法 安全
MD5加密
MD5(Message-Digest Algorithm 5)是一种单向加密算法,将任意长度的数据转换为128位固定长度的散列值,主要用于数据完整性校验和密码存储。其特点包括不可逆运算、高度离散性和相同输入生成一致结果。然而,MD5存在碰撞风险,直接加密密码不安全,需配合“加盐”处理增强安全性。文中提供了未加盐的MD5工具类`MD5Utils`,核心方法`msgToMD5`实现基本加密功能。尽管MD5理论上不可逆,但通过彩虹表等手段可能存在伪破解风险,建议结合多种加密算法提升安全性。
521 2
|
9月前
|
机器学习/深度学习 数据可视化 PyTorch
深入解析图神经网络注意力机制:数学原理与可视化实现
本文深入解析了图神经网络(GNNs)中自注意力机制的内部运作原理,通过可视化和数学推导揭示其工作机制。文章采用“位置-转移图”概念框架,并使用NumPy实现代码示例,逐步拆解自注意力层的计算过程。文中详细展示了从节点特征矩阵、邻接矩阵到生成注意力权重的具体步骤,并通过四个类(GAL1至GAL4)模拟了整个计算流程。最终,结合实际PyTorch Geometric库中的代码,对比分析了核心逻辑,为理解GNN自注意力机制提供了清晰的学习路径。
650 7
深入解析图神经网络注意力机制:数学原理与可视化实现
|
9月前
|
机器学习/深度学习 缓存 自然语言处理
深入解析Tiktokenizer:大语言模型中核心分词技术的原理与架构
Tiktokenizer 是一款现代分词工具,旨在高效、智能地将文本转换为机器可处理的离散单元(token)。它不仅超越了传统的空格分割和正则表达式匹配方法,还结合了上下文感知能力,适应复杂语言结构。Tiktokenizer 的核心特性包括自适应 token 分割、高效编码能力和出色的可扩展性,使其适用于从聊天机器人到大规模文本分析等多种应用场景。通过模块化设计,Tiktokenizer 确保了代码的可重用性和维护性,并在分词精度、处理效率和灵活性方面表现出色。此外,它支持多语言处理、表情符号识别和领域特定文本处理,能够应对各种复杂的文本输入需求。
1144 6
深入解析Tiktokenizer:大语言模型中核心分词技术的原理与架构
|
9月前
|
传感器 人工智能 监控
反向寻车系统怎么做?基本原理与系统组成解析
本文通过反向寻车系统的核心组成部分与技术分析,阐述反向寻车系统的工作原理,适用于适用于商场停车场、医院停车场及火车站停车场等。如需获取智慧停车场反向寻车技术方案前往文章最下方获取,如有项目合作及技术交流欢迎私信作者。
690 2
|
9月前
|
负载均衡 JavaScript 前端开发
分片上传技术全解析:原理、优势与应用(含简单实现源码)
分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
10月前
|
云安全 安全 数据建模
《数字证书:互联网世界的"身份证"与"防盗门"》 ——揭秘网络安全背后的加密江湖
在2023年某深夜,上海陆家嘴金融公司机房遭遇黑客攻击,神秘青铜大门与九大掌门封印的玉牌突现,阻止了入侵。此门象征数字证书,保障网络安全。数字证书如验钞机识别假币,保护用户数据。它通过SSL/TLS加密、CA认证和非对称加密,构建安全通信。证书分为DV、OV、EV三类,分别适合不同场景。忽视证书安全可能导致巨额损失。阿里云提供一站式证书服务,助力企业部署SSL证书,迎接未来量子计算和物联网挑战。
|
12月前
|
安全 算法 网络协议
【网络原理】——图解HTTPS如何加密(通俗简单易懂)
HTTPS加密过程,明文,密文,密钥,对称加密,非对称加密,公钥和私钥,证书加密
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将从网络安全漏洞、加密技术和安全意识三个方面进行探讨,旨在提高读者对网络安全的认识和防范能力。通过分析常见的网络安全漏洞,介绍加密技术的基本原理和应用,以及强调安全意识的重要性,帮助读者更好地保护自己的网络信息安全。
229 10
|
存储 SQL 安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将介绍网络安全的重要性,分析常见的网络安全漏洞及其危害,探讨加密技术在保障网络安全中的作用,并强调提高安全意识的必要性。通过本文的学习,读者将了解网络安全的基本概念和应对策略,提升个人和组织的网络安全防护能力。

推荐镜像

更多
  • DNS