哈希算法--MD5算法

1. Hash算法

哈希算法也称摘要算法、散列算法,哈希函数的输入为一段可变长度x,输出一固定长度串,该串被称为x的哈希值
Hash函数满足以下几个基本需求:
(1)输入值x为任意长度
(2)输出值长度固定
(3)单向函数,算法不可逆
(4)唯一性,很难找到两个不同的输入会得到相同的Hash输出值

2. 概要

MD5信息摘要算法,一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。这套算法的程序在 RFC 1321 标准中被加以规范。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。

3. 算法原理

a. 填充

消息长度应为一个比512bit的倍数少64bit的数,即:
512*n+448

512*n-64

填充方法:在消息后添加一个1,再后接多个0
后64bit为填充前消息长度
如下图所示:
在这里插入图片描述
这样可以对明文分组,每组长度为512bit,即16个长度为32bit的字。

b. 迭代

标准幻数
MD5输出为128bit,即4个32bit的字,可用A、B、C、D表示。
A、B、C、D为标准幻数,其初始值分别为:
A=01234567
B=89ABCDEF
C=FEDCBA98
D=76543210

对于每512bit输入,MD5运算64步,得到128bit输出,该输出参与下一轮输入,如图所示:
在这里插入图片描述
每轮中512bit分为16份,每份32bit,即4B,分别参与4轮运算中16步迭代运算,因此4轮共64步。

在这里插入图片描述逻辑函数F、G、H、I分别如下:
F( X ,Y ,Z ) = ( X & Y ) | ( (~X) & Z )
G( X ,Y ,Z ) = ( X & Z ) | ( Y & (~Z) )
H( X ,Y ,Z ) =X ^ Y ^ Z
I( X ,Y ,Z ) =Y ^ ( X | (~Z) )

4. 应用场景

数据完整性校验
常用Web服务器本身缺乏页面完整性验证机制,无法防止站点文件被篡改。为确保文件的完整性,防止用户访问页面被篡改,可采用MD5算法校验文件完整性的Web防篡改机制,计算目标文件的数字指纹,运用快照技术恢复被篡改文件,以解决多数防篡改系统对动态站点保护失效及小文件恢复难的问题 。
密码加密
我们知道MD5加密是不可逆的,用MD5算法加密后的字符串,是无法反向推算出原始密码的,可以有效防止密码被盗,但是固定长度的纯文本加密容易被撞库,既然如此,那么我们就要对密码加盐。服务器在保存密码时,会生成一段随机字符串并添加到密码后再做MD5散列,确保密码的安全性。

数字签名
MD5 算法还可以作为一种电子签名的方法来使用,使用 MD5算法就可以为任何文件(不管其大小、格式、数量)产生一个独一无二的“数字指纹”,借助这个“数字指纹”,通过检查文件前后 MD5 值是否发生了改变,就可以知道源文件是否被改动。我们在下载软件的时候经常会发现,软件的下载页面上除了会提供软件的下载地址以外,还会给出一串长长的字符串。这串字符串其实就是该软件的MD5 值,它的作用就在于下载该软件后,对下载得到的文件用专门的软件(如 Windows MD5 check 等)做一次 MD5 校验,以确保我们获得的文件与该站点提供的文件为同一文件。利用 MD5 算法来进行文件校验的方案被大量应用到软件下载站、论坛数据库、系统文件安全等方面。

注意
Hash算法不是加密算法。
hash算法也被称为摘要算法、散列算法,其过程不可逆,目的主要是确保数据的完整性。
加密算法的目的主要是确保数据的保密性。

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MD5是一种常见的哈希算法,可以将任意长度的数据转换为固定长度的哈希值。以下是一个使用C语言实现MD5哈希算法的例子: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) void md5(const uint8_t *initial_msg, size_t initial_len, uint8_t *digest) { // 初始化变量 uint32_t h0, h1, h2, h3; h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476; // 消息填充 uint8_t *msg = NULL; size_t new_len, offset; for (new_len = initial_len + 1; new_len % 64 != 56; new_len++); msg = (uint8_t*)calloc(new_len + 8, 1); memcpy(msg, initial_msg, initial_len); msg[initial_len] = 0x80; offset = new_len - 8; *((uint64_t*)(msg + offset)) = (uint64_t)initial_len * 8; // 处理消息块 uint32_t *w = (uint32_t *)msg; uint32_t a, b, c, d, i, f, g, temp; for (i = 0; i < new_len; i += 16) { a = h0; b = h1; c = h2; d = h3; // Round 1 for (uint8_t j = 0; j < 16; j++) { f = (b & c) | ((~b) & d); g = j; temp = d; d = c; c = b; b = b + LEFTROTATE((a + f + w[g] + 0x5A827999), 5); a = temp; } // Round 2 for (uint8_t j = 16; j < 32; j++) { f = (d & b) | ((~d) & c); g = (5 * j + 1) % 16; temp = d; d = c; c = b; b = b + LEFTROTATE((a + f + w[g] + 0x6ED9EBA1), 5); a = temp; } // Round 3 for (uint8_t j = 32; j < 48; j++) { f = b ^ c ^ d; g = (3 * j + 5) % 16; temp = d; d = c; c = b; b = b + LEFTROTATE((a + f + w[g] + 0x8F1BBCDC), 5); a = temp; } // Round 4 for (uint8_t j = 48; j < 64; j++) { f = c ^ (b | (~d)); g = (7 * j) % 16; temp = d; d = c; c = b; b = b + LEFTROTATE((a + f + w[g] + 0xCA62C1D6), 5); a = temp; } // 更新哈希值 h0 += a; h1 += b; h2 += c; h3 += d; } // 释放内存 free(msg); // 生成哈希值 *((uint32_t*)(digest)) = h0; *((uint32_t*)(digest + 4)) = h1; *((uint32_t*)(digest + 8)) = h2; *((uint32_t*)(digest + 12)) = h3; } int main() { uint8_t digest[16]; char *msg = "hello world"; md5((uint8_t*)msg, strlen(msg), digest); for (int i = 0; i < 16; i++) { printf("%02x", digest[i]); } return 0; } ``` 在这个例子中,我们使用了C语言和标准库函数来实现MD5哈希算法。首先,我们定义了一个`md5`函数,该函数接受输入消息、输入长度和哈希值缓冲区,并将哈希值存储在缓冲区中。 在`md5`函数中,我们首先初始化了四个32位的变量`h0`、`h1`、`h2`和`h3`,这些变量将用于存储哈希值。然后,我们对输入消息进行填充,以确保其长度为64的倍数。接下来,我们将填充后的消息分成16个32位的块,并使用四个循环来处理每个块。 在每个循环中,我们使用一系列运算来更新哈希值。具体来说,我们使用了四个轮(Round 1、Round 2、Round 3和Round 4),每个轮使用不同的逻辑函数和常量。最后,我们将更新后的哈希值存储在变量`h0`、`h1`、`h2`和`h3`中,并将其转换为字节序列,存储在哈希值缓冲区中。 在`main`函数中,我们定义了一个输入消息字符串,并使用`md5`函数将其哈希为一个16字节的哈希值。最后,我们打印出哈希值的十六进制表示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值