Tuesday, May 22, 2012

calculate MD5 Digest

Digest is a practical technique to verify that a file is not corrupted. For example, If a rpm file is transferred over internet, Before installing, it is always good practice to verify that the file is not corrupted. The most popular practices are verifying the digest of the received file. If you have a digest already with you, then generate digest on the received file and compare both. If both matches, then it is confirmed that the file is correct. else file is corrupted. Digest will definitely vary even if a single bit varies in a file.

Digest is a fixed length of string which is a result of hash on blocks of input message.
Depending on the hash technique, the digest length varies.

There are various types of standards of calculating digest. For example, MD2,MD4,MD5,SHA1,SHA..etc.
MD5 generates 16bytes of Digest where as SHA digest is of 20bytes long.


Lets see how to calculate MD5 digest.
This program is written using most popular security and cryptography library called openssl. openssl provides various techniques to generate digest. Following APIs are available to generate MD5 Digest on given string. Header file openssl/md5.h should be included which is located at /usr/include/openssl.

 unsigned char *MD5(const unsigned char *d, unsigned long n,
                  unsigned char *md);
 int MD5_Init(MD5_CTX *c);
 int MD5_Update(MD5_CTX *c, const void *data,
                  unsigned long len);
 int MD5_Final(unsigned char *md, MD5_CTX *c);

#include <openssl/md5.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>


#define MAX_BUF_LEN  (128)


int main(int argc, char *argv[])
{
  unsigned char buf[MAX_BUF_LEN];
  int fd=0;
  int len,i=0;


  MD5_CTX c;
  unsigned char hash[MD5_DIGEST_LENGTH];


  /* File name is required */
  if( argc < 2 ) {
     fprintf(stderr,"Usage: %s <filename>\n",argv[0]);
      return 1;
  }


  fd=open(argv[1],O_RDONLY);
  if( fd < 0 ){
      fprintf(stderr,"ERROR: Unable to open file '%s'\n",argv[1]);
      return 1;
  }


  MD5_Init(&c);


  /* Read file in MAX_BUF_LEN chunks
     and pass it to update functions
   */
  while ( len=read(fd,buf,MAX_BUF_LEN) )
      MD5_Update(&c,buf,len);


  MD5_Final(hash,&c);


  fprintf(stdout,"MD5(%s)= ",argv[1]);
  while ( i<MD5_DIGEST_LENGTH) {
     fprintf(stdout,"%02x",(unsigned int)hash[i]);
     i++;
  }


  printf("\n");
  close(fd);
}




A test file is used here on which MD5 digest is calculated and it is compared with the openssl MD5 digest at the end.

prompt# cat test
This is a test program by ncooltips.com
prompt#
prompt# gcc md5.c -o md5 -lssl
prompt# ./md5 test
MD5(test)= b0286ad855b2ce5ce3c7da6c1db43c3d



Calculate MD5 using openssl command, and compare. Both are same.


prompt# openssl md5 test

MD5(test)= b0286ad855b2ce5ce3c7da6c1db43c3d





Lets modify the content of the file, added ";" at the end of the file and see what will be digest.

prompt# vi test

prompt# cat test  
This is a test program by ncooltips.com;


prompt# ./md5 test
MD5(test)= 33bc1afb8e975dbca2ec4f491940062a
prompt# openssl md5 test
MD5(test)= 33bc1afb8e975dbca2ec4f491940062a
prompt#


The digest varied.

Please leave your comments.
Pin It
Related Posts Plugin for WordPress, Blogger...