MD5算法实验报告(XDU物联网安全)
個人博客地址: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+i]=0;}long len=(long)(str_length<<3);for(int i=0;i<8;i++){tempBytes[56+i]=(byte)(len&0xFFL);len=len>>8;}groups=Create_NewGroup(tempBytes,0);Transform(groups);}else{for(int i=0;i<rest;i++)tempBytes[i]=inputBytes[str_length-rest+i];tempBytes[rest]=(byte)(1<<7);for(int i=rest+1;i<64;i++)tempBytes[i]=0;groups=Create_NewGroup(tempBytes,0);Transform(groups);for(int i=0;i<56;i++)tempBytes[i]=0;long len=(long)(str_length<<3);for(int i=0;i<8;i++){tempBytes[56+i]=(byte)(len&0xFFL);len=len>>8;}groups=Create_NewGroup(tempBytes,0);Transform(groups);}return ToHexString();}private String ToHexString(){ //Hash值轉換成十六進制的字符串String resStr="";long temp=0;for(int i=0;i<4;i++){for(int j=0;j<4;j++){temp=result[i]&0x0FL;String a=hexs[(int)(temp)];result[i]=result[i]>>4;temp=result[i]&0x0FL;resStr+=hexs[(int)(temp)]+a;result[i]=result[i]>>4;}}return resStr;}private void Transform(long[] groups) { //對分組進行處理,每個分組64字節long a = result[0], b = result[1], c = result[2], d = result[3];//第一輪a = FF(a, b, c, d, groups[0], S11, 0xd76aa478L);d = FF(d, a, b, c, groups[1], S12, 0xe8c7b756L);c = FF(c, d, a, b, groups[2], S13, 0x242070dbL);b = FF(b, c, d, a, groups[3], S14, 0xc1bdceeeL);a = FF(a, b, c, d, groups[4], S11, 0xf57c0fafL);d = FF(d, a, b, c, groups[5], S12, 0x4787c62aL);c = FF(c, d, a, b, groups[6], S13, 0xa8304613L);b = FF(b, c, d, a, groups[7], S14, 0xfd469501L);a = FF(a, b, c, d, groups[8], S11, 0x698098d8L);d = FF(d, a, b, c, groups[9], S12, 0x8b44f7afL);c = FF(c, d, a, b, groups[10], S13, 0xffff5bb1L);b = FF(b, c, d, a, groups[11], S14, 0x895cd7beL);a = FF(a, b, c, d, groups[12], S11, 0x6b901122L);d = FF(d, a, b, c, groups[13], S12, 0xfd987193L);c = FF(c, d, a, b, groups[14], S13, 0xa679438eL);b = FF(b, c, d, a, groups[15], S14, 0x49b40821L);//第二輪a = GG(a, b, c, d, groups[1], S21, 0xf61e2562L);d = GG(d, a, b, c, groups[6], S22, 0xc040b340L);c = GG(c, d, a, b, groups[11], S23, 0x265e5a51L);b = GG(b, c, d, a, groups[0], S24, 0xe9b6c7aaL);a = GG(a, b, c, d, groups[5], S21, 0xd62f105dL);d = GG(d, a, b, c, groups[10], S22, 0x2441453L);c = GG(c, d, a, b, groups[15], S23, 0xd8a1e681L);b = GG(b, c, d, a, groups[4], S24, 0xe7d3fbc8L);a = GG(a, b, c, d, groups[9], S21, 0x21e1cde6L);d = GG(d, a, b, c, groups[14], S22, 0xc33707d6L);c = GG(c, d, a, b, groups[3], S23, 0xf4d50d87L);b = GG(b, c, d, a, groups[8], S24, 0x455a14edL);a = GG(a, b, c, d, groups[13], S21, 0xa9e3e905L);d = GG(d, a, b, c, groups[2], S22, 0xfcefa3f8L);c = GG(c, d, a, b, groups[7], S23, 0x676f02d9L);b = GG(b, c, d, a, groups[12], S24, 0x8d2a4c8aL);//第三輪a = HH(a, b, c, d, groups[5], S31, 0xfffa3942L);d = HH(d, a, b, c, groups[8], S32, 0x8771f681L);c = HH(c, d, a, b, groups[11], S33, 0x6d9d6122L);b = HH(b, c, d, a, groups[14], S34, 0xfde5380cL);a = HH(a, b, c, d, groups[1], S31, 0xa4beea44L);d = HH(d, a, b, c, groups[4], S32, 0x4bdecfa9L);c = HH(c, d, a, b, groups[7], S33, 0xf6bb4b60L);b = HH(b, c, d, a, groups[10], S34, 0xbebfbc70L);a = HH(a, b, c, d, groups[13], S31, 0x289b7ec6L);d = HH(d, a, b, c, groups[0], S32, 0xeaa127faL);c = HH(c, d, a, b, groups[3], S33, 0xd4ef3085L);b = HH(b, c, d, a, groups[6], S34, 0x4881d05L);a = HH(a, b, c, d, groups[9], S31, 0xd9d4d039L);d = HH(d, a, b, c, groups[12], S32, 0xe6db99e5L);c = HH(c, d, a, b, groups[15], S33, 0x1fa27cf8L);b = HH(b, c, d, a, groups[2], S34, 0xc4ac5665L);//第四輪a = II(a, b, c, d, groups[0], S41, 0xf4292244L);d = II(d, a, b, c, groups[7], S42, 0x432aff97L);c = II(c, d, a, b, groups[14], S43, 0xab9423a7L);b = II(b, c, d, a, groups[5], S44, 0xfc93a039L);a = II(a, b, c, d, groups[12], S41, 0x655b59c3L);d = II(d, a, b, c, groups[3], S42, 0x8f0ccc92L);c = II(c, d, a, b, groups[10], S43, 0xffeff47dL);b = II(b, c, d, a, groups[1], S44, 0x85845dd1L);a = II(a, b, c, d, groups[8], S41, 0x6fa87e4fL);d = II(d, a, b, c, groups[15], S42, 0xfe2ce6e0L);c = II(c, d, a, b, groups[6], S43, 0xa3014314L);b = II(b, c, d, a, groups[13], S44, 0x4e0811a1L);a = II(a, b, c, d, groups[4], S41, 0xf7537e82L);d = II(d, a, b, c, groups[11], S42, 0xbd3af235L);c = II(c, d, a, b, groups[2], S43, 0x2ad7d2bbL);b = II(b, c, d, a, groups[9], S44, 0xeb86d391L);result[0] += a; //加到先前計算結果中result[1] += b;result[2] += c;result[3] += d;result[0]=result[0]&0xFFFFFFFFL;result[1]=result[1]&0xFFFFFFFFL;result[2]=result[2]&0xFFFFFFFFL;result[3]=result[3]&0xFFFFFFFFL;}private long DealHi(byte b){ //需要對符號位進行處理return b < 0 ? b & 0x7F + 128 : b;}private long[] Create_NewGroup(byte[] inputBytes,int index){long [] temp=new long[16]; //將每一個512位的分組再細分成16個小組,每個小組64位(8個字節)for(int i=0;i<16;i++){temp[i]=DealHi(inputBytes[4*i+index])|(DealHi(inputBytes[4*i+1+index]))<<8|(DealHi(inputBytes[4*i+2+index]))<<16|(DealHi(inputBytes[4*i+3+index]))<<24;}return temp;}private long F(long x, long y, long z) {return (x & y) | ((~x) & z);}private long G(long x, long y, long z) {return (x & z) | (y & (~z));}private static long H(long x, long y, long z) {return x ^ y ^ z;}private long I(long x, long y, long z) {return y ^ (x | (~z));}private long FF(long a, long b, long c, long d, long x, long s,long ac) {a += (F(b, c, d)&0xFFFFFFFFL) + x + ac;a = ((a&0xFFFFFFFFL)<< s) | ((a&0xFFFFFFFFL) >>> (32 - s));a += b;return (a&0xFFFFFFFFL);}private long GG(long a, long b, long c, long d, long x, long s,long ac) {a += (G(b, c, d)&0xFFFFFFFFL) + x + ac;a = ((a&0xFFFFFFFFL) << s) | ((a&0xFFFFFFFFL) >>> (32 - s));a += b;return (a&0xFFFFFFFFL);}private long HH(long a, long b, long c, long d, long x, long s,long ac) {a += (H(b, c, d)&0xFFFFFFFFL) + x + ac;a = ((a&0xFFFFFFFFL) << s) | ((a&0xFFFFFFFFL) >>> (32 - s));a += b;return (a&0xFFFFFFFFL);}private long II(long a, long b, long c, long d, long x, long s,long ac) {a += (I(b, c, d)&0xFFFFFFFFL) + x + ac;a = ((a&0xFFFFFFFFL) << s) | ((a&0xFFFFFFFFL) >>> (32 - s));a += b;return (a&0xFFFFFFFFL);} } public class IOT_md5 {public static void main(String []args){String str="Embrace the glorious mess that you are";MD5 md=new MD5(str);} }總結
以上是生活随笔為你收集整理的MD5算法实验报告(XDU物联网安全)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php函数的初步使用
- 下一篇: bootstrap学习笔记(一)网络系统