Wednesday, June 13, 2012

calculate MD5 Digest using EVP API


Previous articles discussed about calculating MD5 Digest and Calculating SHA Digest using openssl API and C program. The above two programs uses MD5 specific apis defined in openssl/md5.h and SHA specific apis defined in openssl/sha.h.

To Make all cryptographic  operations generic, openssl provided envelope APIs referred as "Digital envelopes". The EVP library provides a high-level interface to cryptographic functions. There are many EVP_ functions.

One of them is EVP_Digest. Here we are going to discuss how to use EVP_Digest API to calculate MD5 digest of a file.


Background:

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 EVP APIs.

#include <openssl/evp.h>


 int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
 int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt);
 int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md,
        unsigned int *s);
 int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
 const EVP_MD *EVP_get_digestbyname(const char *name);

 #define EVP_MAX_MD_SIZE 64     /* SHA512 */



#include <openssl/evp.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;
  EVP_MD_CTX c;
  const EVP_MD *md;
  unsigned char buf[MAX_BUF_LEN];
  int fd=0;
  int len,i=0;


  unsigned char hash[EVP_MAX_MD_SIZE];


  /* 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;
  }


  OpenSSL_add_all_digests();


  md = EVP_get_digestbyname("md5");


  EVP_MD_CTX_init(&c);
  EVP_DigestInit_ex(&c, md, NULL);


  /* Read file in MAX_BUF_LEN chunks
     and pass it to update functions
   */
  while ( len=BIO_read(b,buf,MAX_BUF_LEN) )
      EVP_DigestUpdate(&c,buf,len);


  EVP_DigestFinal_ex(&c, hash, &len);
  EVP_MD_CTX_cleanup(&c);
  BIO_free(b);


  fprintf(stdout,"MD5(%s)= ",argv[1]);
  while ( i<len) {
     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 # gcc md5_evp.c -o md5_evp -lssl

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


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




The digest verified.
Read the below articles to see how to calculate Digest using MD5 and SHA APIs.
calculating MD5 Digest
Calculating SHA Digest

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