信息安全实验五:散列算法 2019.05.18

实验散列算法

一、实验目的

理解、掌握MD5散列算法的基本过程。

二、实验内容

  1. 理解MD5散列算法的基本过程。
  2. 分析阅读MD5源代码
  3. 调用MD5源代码,能对任意文件计算出文件的散列值。

三、MD5散列算法基本原理

 

(本次实验参考了MD5 的rfc文档 地址https://www.ietf.org/rfc/rfc1321.txt,我翻译的不是很好。

还参考了博客https://blog.csdn.net/Arrow2013/article/details/43482609

假设有b位长度的原始数据。m_0 m_1 ... m_{b-1},算法总共有5步。

(注:这里的字都是32位。)

 

Step 1. Append Padding Bits

填充原始数据到448模512位,具体如下:首先填充一位1,然后填充若

个0,总共填充1~512位。

Step 2. Append Length

填充一个64比特的b,b代表还未填充的原始数据的值。(假如b超过2^64即超出了64比特所能表示的范围,则只取较低的64位),它是由两个32位字组成的,而且要以按32位字的小端序附加到第一步的后面。

经过填充以后的比特序列的长度是512的倍数,也就是16个32位字的倍数。

M[0 ... N-1] 代表结果的字们,N是16的倍数。

Step 3. Initialize MD Buffer

    一个4字的buffer(A,B,C,D) 被用来计算消息摘要。每个字都是32位寄存器,内存中的值如下,16进制,按字节小端序。

word A: 01 23 45 67

word B: 89 ab cd ef

word C: fe dc ba 98

word D: 76 54 32 10

Step 4. Process Message in 16-Word Blocks

定义以下4个函数:

F(X,Y,Z) = XY v not(X) Z

G(X,Y,Z) = XZ v Y not(Z)

H(X,Y,Z) = X xor Y xor Z

I(X,Y,Z) = Y xor (X v not(Z))

 

#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))

#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))

#define H(x, y, z) ((x) ^ (y) ^ (z))

#define I(x, y, z) ((y) ^ ((x) | ~(z)))

 

这里x,y,z都是一个比特,F可以理解为一个条件语句if X then Y else Z.还可以用+代替“或”,因为一个是x,一个是not(x) ,两者不可能同时为1。非常有意思的是如果xyz是互相独立且非偏置的,f的输出也同样互相独立且非偏置的。

函数G,H,I同F相似,它们都是为了“按位并行”,这样它们的输出也是互相独立非偏置的。注意H函数是一个异或函数,或平均函数,(对它的3个输入异或类似于求平均,不偏心)。

这一步使用了由正弦函数构造的含有64个元素的表,T[i]表示第i个元素,且  ,i是弧度制的,这个表是常量表,附录会给出,代码中也有计算的函数,只用计算一遍即可得出。

 

具体步骤:(由于过程简单且注解齐全,故不再赘述)

   For i = 0 to N/16-1 do

     /* Copy block i into X. */

     For j = 0 to 15 do

       Set X[j] to M[i*16+j].

     end /* of loop on j */

 

     /* Save A as AA, B as BB, C as CC, and D as DD. */

     AA = A

     BB = B

     CC = C

     DD = D

 

     /* Round 1. */

     /* Let [abcd k s i] denote the operation

          a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */

     /* Do the following 16 operations. */

     [ABCD  0  7  1]  [DABC  1 12  2] [CDAB  2 17  3]  [BCDA  3 22  4]

     [ABCD  4  7  5]  [DABC  5 12  6] [CDAB  6 17  7]  [BCDA  7 22  8]

     [ABCD  8  7  9]  [DABC  9 12 10] [CDAB 10 17 11]  [BCDA 11 22 12]

     [ABCD 12  7 13]  [DABC 13 12 14] [CDAB 14 17 15]  [BCDA 15 22 16]

 

     /* Round 2. */

     /* Let [abcd k s i] denote the operation

          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */

     /* Do the following 16 operations. */

     [ABCD  1  5 17]  [DABC  6  9 18]  [CDAB 11 14 19]  [BCDA  0 20 20]

     [ABCD  5  5 21]  [DABC 10  9 22]  [CDAB 15 14 23]  [BCDA  4 20 24]

     [ABCD  9  5 25]  [DABC 14  9 26]  [CDAB  3 14 27]  [BCDA  8 20 28]

     [ABCD 13  5 29]  [DABC  2  9 30]  [CDAB  7 14 31]  [BCDA 12 20 32]

 

     /* Round 3. */

     /* Let [abcd k s t] denote the operation

          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */

     /* Do the following 16 operations. */

     [ABCD  5  4 33]  [DABC  8 11 34]  [CDAB 11 16 35]  [BCDA 14 23 36]

     [ABCD  1  4 37]  [DABC  4 11 38]  [CDAB  7 16 39]  [BCDA 10 23 40]

     [ABCD 13  4 41]  [DABC  0 11 42]  [CDAB  3 16 43]  [BCDA  6 23 44]

     [ABCD  9  4 45]  [DABC 12 11 46]  [CDAB 15 16 47]  [BCDA  2 23 48]

 

     /* Round 4. */

     /* Let [abcd k s t] denote the operation

          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */

     /* Do the following 16 operations. */

     [ABCD  0  6 49]  [DABC  7 10 50]  [CDAB 14 15 51]  [BCDA  5 21 52]

     [ABCD 12  6 53]  [DABC  3 10 54]  [CDAB 10 15 55]  [BCDA  1 21 56]

     [ABCD  8  6 57]  [DABC 15 10 58]  [CDAB  6 15 59]  [BCDA 13 21 60]

     [ABCD  4  6 61]  [DABC 11 10 62]  [CDAB  2 15 63]  [BCDA  9 21 64]

 

     /* Then perform the following additions. (That is increment each

        of the four registers by the value it had before this block

        was started.) */

     A = A + AA

     B = B + BB

     C = C + CC

     D = D + DD

 

   end /* of loop on i */

 

 

Step 5. Output

输出A,B,C,D 合计4*32位,最终长度为32的16进制数。

四、实验过程

 

关键代码

// 程序可以一个或多个文件进行MD5

#include <iostream>

#include "md5.h"

/* Prints a message digest in hexadecimal.

 */

static void MDPrint(unsigned char digest[16])

{

unsigned int i;

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

printf("%02x", digest[i]);

}

/* Digests a file and prints the result.

 */

static void MDFile(char* filename)

{

FILE* file;

md5_state_s st;

int len;

unsigned char buffer[1024];

md5_byte_t digest[16];

if ((file = fopen(filename, "rb")) == NULL) {

printf("%s can't be opened\n", filename);

}

else {

md5_init(&st);

while ((len = fread(buffer, 1, 1024, file)))

md5_append(&st, buffer, len);

md5_finish( &st, digest);

 

fclose(file);

 

printf("MD%d (%s) = ", 5, filename);

MDPrint(digest);

printf("\n");

}

}

 

int main(int argc, char* argv[])

{

int i;

if (argc > 1) {

for (i = 1; i < argc; i++) {

MDFile(argv[i]);

}

}

else {

printf(" usage: MDFile file1 [file2 ...]\n");

}

return (0);

}

 

 

 

五、实验结果

 

我自己按照要求写的MDFile.exe和网上找到的完整项目RFC1321_MD5.exe出来的一样,说明实验成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值