Tuesday, June 5, 2012

Calculate MD5 Digest - Using BIO APIs



Previous articles discussed about calculating MD5 Digest and Calculating SHA Digest using openssl API and C program. The above two programs are written using stdio file input output APIs. These APIs are platform dependent.

To avoid this problem, openSSL provides an I/O abstraction , it hides many of the underlying I/O details from an application. That is BIO API library. This post explains calculate MD5 digest using openssl,BIO APIs.




Background:

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 using openssl and BIO APIs.
Lets concentrate more on the BIO APIs. The following APIs are used to open file, read file and close file.

#include <openssl/md5.h>
BIO *test; /* BIO Object pointer */
BIO   *BIO_new_file(const char *filename, const char *mode);
int   BIO_read(BIO *b, void *buf, int len);
int    BIO_free(BIO *a);


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


#define MAX_BUF_LEN  (128)


int main(int argc, char *argv[])
{
  BIO *b=NULL;
  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;
  }


  b=BIO_new_file(argv[1], "r");
  if( b == NULL ){
      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=BIO_read(b,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++;
  }


  BIO_free(b);


  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# gcc md5_bio.c -lssl -o md5_bio

prompt# ./md5_bio test
MD5(test)= 33bc1afb8e975dbca2ec4f491940062a

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




The digest verified.
You can try SHA Digest using BIO read logic.

Please leave your comments. Kindly share this post.
Pin It
Related Posts Plugin for WordPress, Blogger...