© 2012 Firstsoft Technologies (P) Limited. login
Hi 'Guest'
Home SiteMap Contact Us Disclaimer
enggedu
Quick Links
Easy Studies
MD5 Algorithm Implementation Using Java

Description:

This program represents the implementation of MD5 algorithm. MD5 algorithm can be used as a digital signature mechanism. Takes as input a message of arbitrary length and produces as output a 128 bit “fingerprint” or “message digest” of the input. MD5 algorithm generates the output as 128 bit hashcode for the input String of any length.  The steps involved in MD5 algorithm are

  1. Pad message so its length is 448 mod 512
  2. Append a 64-bit original length value to message
  3. Initialise 4-word (128-bit) MD buffer (A,B,C,D)
  4. Process message in 16-word (512-bit) blocks:
    1. Using 4 rounds of 16 bit operations on message block & buffer
    2. Add output to buffer input to form new buffer value
  5. Output hash value is the final buffer value

This program uses getBytes() method to encode the String into a sequence of bytes using the platform's default charset, storing the result into a new byte array. These byte array data is converted into hashcode by invoking the following methods update (byte[]), md5final (byte[]), dumpBytes (byte[]).

MD5 Algorithm Implementation Using Java:

//MD5.java import java.io.*; import java.net.*; import java.util.*; import java.math.*; public class MD5 { int buf[]; long bits; byte in[]; int inint[]; public MD5() { buf = new int[4]; // fill the hash accumulator with a seed value buf[0] = 0x67452301; buf[1] = 0xefcdab89; buf[2] = 0x98badcfe; buf[3] = 0x10325476; // initially, we've hashed zero bits bits = 0L; in = new byte[64]; inint = new int[16]; } public void update(byte[] newbuf) { update(newbuf, 0, newbuf.length); } public void update(byte[] newbuf, int length) { update(newbuf, 0, length); } public void update(byte[] newbuf, int bufstart, int buflen) { int t; int len = buflen; // shash old bits value for the "Bytes already in" computation // just below. t = (int) bits; // (int) cast should just drop high bits, I hope /* update bitcount */ /* the C code used two 32-bit ints separately, and carefully * ensured that the carry carried. * Java has a 64-bit long, which is just what the code really wants. */ bits += (long)(len<<3); t = (t >>> 3) & 0x3f; /* Bytes already in this->in */ /* Handle any leading odd-sized chunks */ /* (that is, any left-over chunk left by last update() */ if (t!=0) { int p = t; t = 64 - t; if (len < t) { System.arraycopy(newbuf, bufstart, in, p, len); return; } System.arraycopy(newbuf, bufstart, in, p, t); transform(); bufstart += t; len -= t; } /* Process data in 64-byte chunks */ while (len >= 64) { System.arraycopy(newbuf, bufstart, in, 0, 64); transform(); bufstart += 64; len -= 64; } /* Handle any remaining bytes of data. */ /* that is, stash them for the next update(). */ System.arraycopy(newbuf, bufstart, in, 0, len); } /* * Final wrapup - pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ public void md5final(byte[] digest) { /* "final" is a poor method name in Java. :v) */ int count; int p; /* Compute number of bytes mod 64 */ count = (int) ((bits >>> 3) & 0x3F); /* Set the first char of padding to 0x80. This is safe since there is always at least one byte free */ p = count; in[p++] = (byte) 0x80; /* Bytes of padding needed to make 64 bytes */ count = 64 - 1 - count; /* Pad out to 56 mod 64 */ if (count < 8) { /* Two lots of padding: Pad the first block to 64 bytes */ zeroByteArray(in, p, count); transform(); /* Now fill the next block with 56 bytes */ zeroByteArray(in, 0, 56); } else { /* Pad block to 56 bytes */ zeroByteArray(in, p, count - 8); } /* Append length in bits and transform */ // Could use a PUT_64BIT... func here. This is a fairly // direct translation from the C code, where bits was an array // of two 32-bit ints. int lowbits = (int) bits; int highbits = (int) (bits >>> 32); PUT_32BIT_LSB_FIRST(in, 56, lowbits); PUT_32BIT_LSB_FIRST(in, 60, highbits); transform(); PUT_32BIT_LSB_FIRST(digest, 0, buf[0]); PUT_32BIT_LSB_FIRST(digest, 4, buf[1]); PUT_32BIT_LSB_FIRST(digest, 8, buf[2]); PUT_32BIT_LSB_FIRST(digest, 12, buf[3]); /* zero sensitive data */ /* notice this misses any sneaking out on the stack. The C * version uses registers in some spots, perhaps because * they care about this. */ zeroByteArray(in); zeroIntArray(buf); bits = 0; zeroIntArray(inint); } public static void main(String args[]) { // This main() method was created to easily test // this class. It hashes whatever's on System.in. byte buf[] = new byte[397]; // arbitrary buffer length designed to irritate update() int rc; MD5 md = new MD5(); byte out[] = new byte[16]; int i; int len = 0; try { while ((rc = System.in.read(buf, 0, 397)) > 0) { md.update(buf, rc); len += rc; } } catch (IOException ex) { ex.printStackTrace(); return; } md.md5final(out); System.out.println("file length: "+len); System.out.println("hash: "+dumpBytes(out)); } private void zeroByteArray(byte[] a) { zeroByteArray(a, 0, a.length); } private void zeroByteArray(byte[] a, int start, int length) { setByteArray(a, (byte) 0, start, length); } private void setByteArray(byte[] a, byte val, int start, int length) { int i; int end = start+length; for (i=start; i<>>(32-s); w += x; return w; } private void transform() { /* load in[] byte array into an internal int array */ int i; int[] inint = new int[16]; for (i=0; i<16; i++) { inint[i] = GET_32BIT_LSB_FIRST(in, 4*i); } int a, b, c, d; a = buf[0]; b = buf[1]; c = buf[2]; d = buf[3]; a = MD5STEP(F1, a, b, c, d, inint[0] + 0xd76aa478, 7); d = MD5STEP(F1, d, a, b, c, inint[1] + 0xe8c7b756, 12); c = MD5STEP(F1, c, d, a, b, inint[2] + 0x242070db, 17); b = MD5STEP(F1, b, c, d, a, inint[3] + 0xc1bdceee, 22); a = MD5STEP(F1, a, b, c, d, inint[4] + 0xf57c0faf, 7); d = MD5STEP(F1, d, a, b, c, inint[5] + 0x4787c62a, 12); c = MD5STEP(F1, c, d, a, b, inint[6] + 0xa8304613, 17); b = MD5STEP(F1, b, c, d, a, inint[7] + 0xfd469501, 22); a = MD5STEP(F1, a, b, c, d, inint[8] + 0x698098d8, 7); d = MD5STEP(F1, d, a, b, c, inint[9] + 0x8b44f7af, 12); c = MD5STEP(F1, c, d, a, b, inint[10] + 0xffff5bb1, 17); b = MD5STEP(F1, b, c, d, a, inint[11] + 0x895cd7be, 22); a = MD5STEP(F1, a, b, c, d, inint[12] + 0x6b901122, 7); d = MD5STEP(F1, d, a, b, c, inint[13] + 0xfd987193, 12); c = MD5STEP(F1, c, d, a, b, inint[14] + 0xa679438e, 17); b = MD5STEP(F1, b, c, d, a, inint[15] + 0x49b40821, 22); a = MD5STEP(F2, a, b, c, d, inint[1] + 0xf61e2562, 5); d = MD5STEP(F2, d, a, b, c, inint[6] + 0xc040b340, 9); c = MD5STEP(F2, c, d, a, b, inint[11] + 0x265e5a51, 14); b = MD5STEP(F2, b, c, d, a, inint[0] + 0xe9b6c7aa, 20); a = MD5STEP(F2, a, b, c, d, inint[5] + 0xd62f105d, 5); d = MD5STEP(F2, d, a, b, c, inint[10] + 0x02441453, 9); c = MD5STEP(F2, c, d, a, b, inint[15] + 0xd8a1e681, 14); b = MD5STEP(F2, b, c, d, a, inint[4] + 0xe7d3fbc8, 20); a = MD5STEP(F2, a, b, c, d, inint[9] + 0x21e1cde6, 5); d = MD5STEP(F2, d, a, b, c, inint[14] + 0xc33707d6, 9); c = MD5STEP(F2, c, d, a, b, inint[3] + 0xf4d50d87, 14); b = MD5STEP(F2, b, c, d, a, inint[8] + 0x455a14ed, 20); a = MD5STEP(F2, a, b, c, d, inint[13] + 0xa9e3e905, 5); d = MD5STEP(F2, d, a, b, c, inint[2] + 0xfcefa3f8, 9); c = MD5STEP(F2, c, d, a, b, inint[7] + 0x676f02d9, 14); b = MD5STEP(F2, b, c, d, a, inint[12] + 0x8d2a4c8a, 20); a = MD5STEP(F3, a, b, c, d, inint[5] + 0xfffa3942, 4); d = MD5STEP(F3, d, a, b, c, inint[8] + 0x8771f681, 11); c = MD5STEP(F3, c, d, a, b, inint[11] + 0x6d9d6122, 16); b = MD5STEP(F3, b, c, d, a, inint[14] + 0xfde5380c, 23); a = MD5STEP(F3, a, b, c, d, inint[1] + 0xa4beea44, 4); d = MD5STEP(F3, d, a, b, c, inint[4] + 0x4bdecfa9, 11); c = MD5STEP(F3, c, d, a, b, inint[7] + 0xf6bb4b60, 16); b = MD5STEP(F3, b, c, d, a, inint[10] + 0xbebfbc70, 23); a = MD5STEP(F3, a, b, c, d, inint[13] + 0x289b7ec6, 4); d = MD5STEP(F3, d, a, b, c, inint[0] + 0xeaa127fa, 11); c = MD5STEP(F3, c, d, a, b, inint[3] + 0xd4ef3085, 16); b = MD5STEP(F3, b, c, d, a, inint[6] + 0x04881d05, 23); a = MD5STEP(F3, a, b, c, d, inint[9] + 0xd9d4d039, 4); d = MD5STEP(F3, d, a, b, c, inint[12] + 0xe6db99e5, 11); c = MD5STEP(F3, c, d, a, b, inint[15] + 0x1fa27cf8, 16); b = MD5STEP(F3, b, c, d, a, inint[2] + 0xc4ac5665, 23); a = MD5STEP(F4, a, b, c, d, inint[0] + 0xf4292244, 6); d = MD5STEP(F4, d, a, b, c, inint[7] + 0x432aff97, 10); c = MD5STEP(F4, c, d, a, b, inint[14] + 0xab9423a7, 15); b = MD5STEP(F4, b, c, d, a, inint[5] + 0xfc93a039, 21); a = MD5STEP(F4, a, b, c, d, inint[12] + 0x655b59c3, 6); d = MD5STEP(F4, d, a, b, c, inint[3] + 0x8f0ccc92, 10); c = MD5STEP(F4, c, d, a, b, inint[10] + 0xffeff47d, 15); b = MD5STEP(F4, b, c, d, a, inint[1] + 0x85845dd1, 21); a = MD5STEP(F4, a, b, c, d, inint[8] + 0x6fa87e4f, 6); d = MD5STEP(F4, d, a, b, c, inint[15] + 0xfe2ce6e0, 10); c = MD5STEP(F4, c, d, a, b, inint[6] + 0xa3014314, 15); b = MD5STEP(F4, b, c, d, a, inint[13] + 0x4e0811a1, 21); a = MD5STEP(F4, a, b, c, d, inint[4] + 0xf7537e82, 6); d = MD5STEP(F4, d, a, b, c, inint[11] + 0xbd3af235, 10); c = MD5STEP(F4, c, d, a, b, inint[2] + 0x2ad7d2bb, 15); b = MD5STEP(F4, b, c, d, a, inint[9] + 0xeb86d391, 21); buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } private int GET_32BIT_LSB_FIRST(byte[] b, int off) { return ((int)(b[off+0]&0xff)) | ((int)(b[off+1]&0xff) << 8) | ((int)(b[off+2]&0xff) << 16) | ((int)(b[off+3]&0xff) << 24); } private void PUT_32BIT_LSB_FIRST(byte[] b, int off, int value) { b[off+0] = (byte) (value & 0xff); b[off+1] = (byte) ((value >> 8) & 0xff); b[off+2] = (byte) ((value >> 16)& 0xff); b[off+3] = (byte) ((value >> 24)& 0xff); } public static String dumpBytes(byte[] bytes) { int i; StringBuffer sb = new StringBuffer(); for (i=0; i< 2) { s = "0"+s; } if (s.length() > 2) { s = s.substring(s.length()-2); } sb.append(s); } return sb.toString(); } } //MD5Implementation.java public class MD5Implementation{ public static void main(String args[]){ String message="Computer"; System.out.println("Input String : "+message); byte buf[] = message.getBytes(); MD5 md = new MD5(); byte out[] = new byte[16]; md.update(buf); md.md5final(out); String nhash = md.dumpBytes(out); System.out.println("MD5 Output(Hashcode) : "+nhash); } }

Sample ScreenShot:

 
SLogix Student Projects


⇓ Student Projects ⇓
⇑ Student Projects ⇑
bottom