MD5算法实验报告(XDU物联网安全)

本文详细介绍了如何利用MD5算法对自定义英文名言进行加密,包括填充规则、代码实现步骤和加密结果分析。通过实际操作,深入理解MD5的加密原理及其实用性。

个人博客地址:https://travis1024.github.io/

MD5算法实验

一、实验目的

编程实现MD5算法,深入理解MD5加密解密原理

二、实验所用仪器(或实验环境)

计算机科学与技术学院实验中心,可接入Internet网台式机44台。

三、实验基本原理及要求

1.实验原理

第一步:添加填充位,如果输入明文的长度(bit)对512求余的结果不等于448,就需要填充使得对512求余的结果等于448。填充的方法是填充一个1和n个0。填充完后,信息的长度为N*512+448(bit)

第二步:填充长度,在第一步结果之后再填充上原消息的长度,可用来进行的存储长度为64位。如果消息长度大于2^64,则只使用其低64位的值,即(消息长度 对 2^64取模)。在此步骤进行完毕后,最终消息长度就是N x 512+448+64=(N+1) x 512。

第三步,初始化缓冲区, 一个128bit的缓冲区可用于保存hash函数中间和最终结果。可表示为4个32bit的寄存器(A,B,C,D). 其中A=(01234567)16,B=(89ABCDEF)16,C=(FEDCBA98)16,D=(76543210)16。如果在程序中定义应该是 A=0X67452301L,B=0XEFCDAB89L,C=0X98BADCFEL,D=0X10325476L

第四步:循环处理数据

其中每一轮操作为

第五步,级联输出,给出MD5算法加密后的密文。

2.实验要求

明文自定义(例如,可以是一句英文名言名句),利用MD5算法对其加密,给出实验过程以及加密结果。

四、实验步骤及实验数据记录:(要有文字描述和必要截图)

1.算法说明

MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

2.代码结构
3.具体实现步骤

(1)我们第一步要做的就是填充,如果输入信息的长度(bit)对512求余的结果 不等于448,就需要填充使得对512求余的结果等于448。填充的方法是填充一个1和n个0。填充完后,信息的长度就为N*512+448(bit);代码如下图所示:

(2)将输入信息的原始长度b(bit)表示成一个64-bit的数字,把它添加到上一步的结果后面(在32位的机器上,这64位将用2个字来表示并且低位在前)。当遇到b大于2^64这种极少的情况时,b的高位被截去,仅使用b的低64位。经过上面两步,数据就被填补成长度为512(bit)的倍数。也就是说,此时的数据长度是16个字(32byte)的整数倍。代码如下图所示:

(3)装入标准的幻数(四个整数),用一个四个字的缓冲器(A,B,C,D)来计算报文摘要,A,B,C,D分别是32位的寄存器,初始化使用的是十六进制表示的数字,注意低字节在前:

​ word A: 01 23 45 67
​ word B: 89 ab cd ef
​ word C: fe dc ba 98
​ word D: 76 54 32 10

(4)四轮循环运算:循环的次数是分组的个数(N+1)

① 定义4个辅助函数,每个函数的输入是三个32位的字,输出是一个32位的字:(&是与,|是或,~是非,^是异或),代码如下图所示:

​ F(X,Y,Z)=(X&Y)|((~X)&Z)
​ G(X,Y,Z)=(X&Z)|(Y&(~Z))
​ H(X,Y,Z)=XYZ
​ I(X,Y,Z)=Y^(X|(~Z))

②设Mj表示消息的第j个子分组(从0到15):代码如下图所示:

​ FF(a,b,c,d,Mj,s,ti)表示a=b+((a+F(b,c,d)+Mj+ti)<<<s)
​ GG(a,b,c,d,Mj,s,ti)表示a=b+((a+G(b,c,d)+Mj+ti)<<<s)
​ HH(a,b,c,d,Mj,s,ti)表示a=b+((a+H(b,c,d)+Mj+ti)<<<s)
​ II(a,b,c,d,Mj,s,ti)表示a=b+((a+I(b,c,d)+Mj+ti)<<<s)

(5)每轮循环后,将A,B,C,D分别加上a,b,c,d,然后进入下一循环

五、实验结果分析

1.实验结果

开始我们传入的字符串为:“Embrace the glorious mess that you are”,最后得到的MD5值为“ADE90D3E14F9114D0EF4626971DE0BD0”。

2.实验总结

任何消息经过散列函数处理后,都会产生一个唯一的散列值,这个散列值可以用来验证消息的完整性,MD5也正是利用了这个特点,通过对MD5算法原理的学习及实验,我对散列函数压缩性、容易计算、抗修改性的特点有了更加深刻的体会,对于MD5算法的验证基本上只有借助计算机才可以进行,因为MD5算法在计算量上相对来说还是比较复杂的,通过计算机我们可以很简单的进行求和运算,当完成最后一个明文的分组运算时,A、B、C、D中的数值就是最后的结果(即散列函数值)。

六、开源地址

实验报告及代码开源地址(Github)

七、源代码

class MD5{
   
   
    //初始化MD5参数
    static final int S11 = 7;
    static final int S12 = 12;
    static final int S13 = 17;
    static final int S14 = 22;
    static final int S21 = 5;
    static final int S22 = 9;
    static final int S23 = 14;
    static final int S24 = 20;
    static final int S31 = 4;
    static final int S32 = 11;
    static final int S33 = 16;
    static final int S34 = 23;
    static final int S41 = 6;
    static final int S42 = 10;
    static final int S43 = 15;
    static final int S44 = 21;
    //定义标准幻数
    private static final long A=0x67452301L;
    private static final long B=0xefcdab89L;
    private static final long C=0x98badcfeL;
    private static final long D=0x10325476L;
    
    private long [] result={
   
   A,B,C,D};  //存储结果
    static final String hexs[]={
   
   "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};
    private String str;

    public MD5(String str) {
   
   
        this.str=str;
        String result=Main_process();
        System.out.println("| MD5---<"+str+">"+" | \nResult: "+result);
    }
    
    private String Main_process() {
   
   
        byte [] inputBytes=str.getBytes();
        int str_length=inputBytes.length;   //字符串字节长度
        int group_number=0;                 //分组个数,每组512位(64字节)
        group_number=str_length/64;         //字节长度/64字节
        long []groups=null;                 //每组按4字节继续细分

        for(int i=0;i<group_number;i++){
   
     //处理分组,循环运算,循环次数位分组个数
            groups=Create_NewGroup(inputBytes,i*64);
            Transform(groups);                     //处理分组,核心算法
        }

        int rest=str_length%64;            //处理512位分组后的余数
        byte [] tempBytes=new byte[64];
        if(rest<=56){
   
   
            for(int i=0;i<rest;i++)
                tempBytes[i]=inputBytes[str_length-rest+i];
            if(rest<56){
   
   
                tempBytes[rest]=(byte)(1<<7);
                for(int i=1;i<56-rest;i++)
                    tempBytes[rest<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值