MD5 Algorithm
MD5 Algorithm
MD5 Algorithm
com
MD5
algorithm can be used as a digital signature mechanism. This presentation will explore the technical aspects of the MD5 algorithm.
Takes as input a message of arbitrary length and produces as output a 128 bit fingerprint or message digest of the input. It is conjectured that it is computationally infeasible to produce two messages having the same message digest. Intended where a large file must be compressed in a secure manner before being encrypted with a private key under a public-key cryptosystem such as PGP.
package com.mkyong.test; import java.io.FileInputStream; import java.security.MessageDigest; public class MD5CheckSumExample { public static void main(String[] args)throws Exception { MessageDigest md = MessageDigest.getInstance("MD5"); FileInputStream fis =newFileInputStream("c:\\loging.log"); byte[] dataBytes = new byte[1024]; int nread = 0;
while ((nread = fis.read(dataBytes)) != -1) { md.update(dataBytes, 0, nread); }; byte[] mdbytes = md.digest(); //convert the byte to hex format method 1 StringBuffer sb = new StringBuffer(); for (int i = 0; i < mdbytes.length; i++) { sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1)); } System.out.println("Digest(in hex format):: " + sb.toString());
//convert the byte to hex format method 2 StringBuffer hexString = new StringBuffer(); for (int i=0;i<mdbytes.length;i++) { String hex=Integer.toHexString(0xff & mdbytes[i]); if(hex.length()==1) hexString.append('0'); hexString.append(hex); } System.out.println("Digest(in hex format):: " + hexString.toString()); } }
Digest(in
Suppose
a b-bit message as input, and that we need to find its message digest.
Step 1 append padded bits: The message is padded so that its length is congruent to 448, modulo 512. Means extended to just 64 bits shy of being of 512 bits long. A single 1 bit is appended to the message, and then 0 bits are appended so that the length in bits equals 448 modulo 512.
Step 2 append length: A 64 bit representation of b is appended to the result of the previous step. The resulting message has a length that is an exact multiple of 512 bits.
Step 3 Initialize MD Buffer A four-word buffer (A,B,C,D) is used to compute the message digest. Here each of A,B,C,D, is a 32 bit register.
Step 3 cont. These registers are initialized to the following values in hexadecimal: 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. Four auxiliary functions that take as input three 32-bit words and produce as output one 32-bit word. 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))
Step 4 Process message in 16-word blocks cont. if the bits of X, Y, and Z are independent and unbiased, the each bit of F(X,Y,Z), G(X,Y,Z), H(X,Y,Z), and I(X,Y,Z) will be independent and unbiased.
Step 5 output The message digest produced as output is A, B, C, D. That is, output begins with the low-order byte of A, and end with the high-order byte of D.
//Note:
All variables are unsigned 32 bits and wrap modulo 2^32 when calculating var int[64] r, k //r specifies the per-round shift amounts r[ 0..15] := {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22} r[16..31] := {5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20} r[32..47] := {4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23} r[48..63] := {6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}
//Use
binary integer part of the sines of integers (Radians) as constants: for i from 0 to 63 k[i] := floor(abs(sin(i + 1)) (2 pow 32))end for //Initialize variables: var int h0 := 0x67452301 var int h1 := 0xEFCDAB89 var int h2 := 0x98BADCFE var int h3 := 0x10325476
//Pre-processing:
append
"1" bit to messageappend "0" bits until message length in bits 448 (mod 512)append length to message /* bit (not byte) length of unpadded message as 64-bit little-endian integer */ //Process the message in successive 512-bit chunks:for each 512-bit chunk of message break chunk into sixteen 32-bit little-endian words w[j], 0 j 15
//Initialize
hash value for this chunk: var int a := h0 var int b := h1 var int c := h2 var int d := h3
//Main loop: for i from 0 to 63 if 0 i 15 then f := (b and c) or ((not b) and d) g := i else if 16 i 31 f := (d and b) or ((not d) and c) g := (5i + 1) mod 16 else if 32 i 47 f := b xor c xor d g := (3i + 5) mod 16 else if 48 i 63 f := c xor (b or (not d)) g := (7i) mod 16 temp := d d := c c := b b := b + leftrotate((a + f + k[i] + w[g]) , r[i]) a := temp end for
//Add
this chunk's hash to result so far: h0 := h0 + a h1 := h1 + b h2 := h2 + c h3 := h3 + d end for var char digest[16] := h0 append h1 append h2 append h3 //(expressed as little-endian) //leftrotate function definition leftrotate (x, c) return (x << c) or (x >> (32-c));
package javaapplicationMD5; import java.security.*; class Md5 { public static void main(String[] a) { try { MessageDigest md = MessageDigest.getInstance("MD5"); System.out.println("Message digest object info: "); System.out.println(" Algorithm = "+md.getAlgorithm()); System.out.println(" Provider = "+md.getProvider()); System.out.println(" toString = "+md.toString());
String
input = ""; md.update(input.getBytes()); byte[] output = md.digest(); System.out.println(); System.out.println("MD5(\""+input+"\") ="); System.out.println(" "+bytesToHex(output));
input = "abc"; md.update(input.getBytes()); output = md.digest(); System.out.println(); System.out.println("MD5(\""+input+"\") ="); System.out.println(" "+bytesToHex(output)); input = "abcdefghijklmnopqrstuvwxyz"; md.update(input.getBytes()); output = md.digest(); System.out.println(); System.out.println("MD5(\""+input+"\") ="); System.out.println(" "+bytesToHex(output));
} catch (Exception e) { System.out.println("Exception: "+e); } } public static String bytesToHex(byte[] b) { char hexDigit[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; StringBuffer buf = new StringBuffer(); for (int j=0; j<b.length; j++) { buf.append(hexDigit[(b[j] >> 4) & 0x0f]); buf.append(hexDigit[b[j] & 0x0f]); }
return buf.toString(); }}
The MD5 algorithm is simple to implement, and provides a fingerprint or message digest of a message of arbitrary length. The difficulty of coming up with two messages with the same message digest is on the order of 2^64 operations