gen 31

Generar i mostrar el MD5 d’un fitxer o cadena

Tag: Programació, c/c++, linuxmad93 @ 11:26 pm

Quan volem verificar el correcte enviament d'un fitxer solem emprar algorismes que generen unes cadenes 'úniques' per tal d'assegurar-nos de que l'arxiu s'ha rebut clavat a l'original. Per a una pràctica així ho he volgut fer, i després d'un parell de dies he entés per fi com anava tot el sistema (una mica lent, sí).

Primerament hem de carregar les capçalera per a poder emprar les funcions md5 d'openssl:

#include <openssl/md5.h>

Amb això podem cridar a les funcions MD5_Init, MD5_Update i MD5_Final. Com indica el nom MD5_Init serveix per iniciar el procés de conversió, inicialitzant una variable del tipus MD5_CTX. Per a l'exemple l'anomenarem state:

MD5_CTX state;

MD5_Update requereix 3 paràmetres. Primerament la nostra variable state, per a seguir i actualitzar el context de les dades de les que crear-ne el MD5. Segon li hem de passar una dada de tipus unsigned char, en el nostre cas anomenada buffer. Aquesta variable el que conté són les dades de les que volem que faci el MD5. Com que el buffer és una estructura dinàmica, el tercer paràmetre és un enter indicant el nombre de caràcters que ha de llegir.

unsigned char *buffer;
int comptador;

Cal tenir en compte que MD5_Update es pot cridar tantes vegades com faci falta fins a carregar totes les dades dessitjades.

Per acabar emprem la funció MD5_Final, que de primer paràmetre ens demana una cadena unsigned char, de 16 bytes, que serà el que es coneix com a digest (la variable l'anomenarem així), que és el MD5 en format binari. Com a darrer paràmetre l'hi passem la variable state, que conté el context del que s'ha de generar el MD5.

unsigned char *digest;

Tot aquest procés ens dona el digest, que és un valor binari. Però el problema és que podem voler tractar el md5 de forma visual, en format de cadena, llegible per a una persona. Per fer això ens podem fer una petita funció a mà.

char *digestAMD5(unsigned char *digest)
{
  static const char HEX_DIGITS[] = "0123456789abcdef";
  char *md5;
  int n;
 
  md5=malloc(sizeof(char)*33);
  for (n = 0; n < 16; n++)
  {
    md5[2*n]   = HEX_DIGITS[(digest[n] >> 4) & 0x0f];
    md5[2*n+1] = HEX_DIGITS[digest[n] & 0xf];
  }
  md5[32] = 0;
 
  return (char *) md5;
}

Aquesta funció ens generaria un MD5 legible per a una persona. Un exemple per veure-ho funcionant tot junt:

#include <openssl/md5.h>
int main()
{
  unsigned char *buffer, *digest;
  int comptador;
  char *md5;
  MD5_CTX state;
 
  //Demanem memòria per a les nostres cadenes
  digest=malloc(sizeof(char)*16);
  md5=malloc(sizeof(char)*33); //El md5 és de 32 caràcters, en posem un més per poder-hi afegir el byte de fi de cadena.
 
  //Carreguem el buffer del lloc que necessitem
  //Això ja depen d'on extrequi cadascú la informació de la que vol fer-ne el md5
 
  //Inicialitzem el entorn
  MD5_Init(&state);
 
  //Afegim les dades del buffer. Es pot anar cridant aquesta funció les vegades que faci falta
  MD5_Update(&state, buffer, comptador);
 
  //Genera el digest de les dades enviades. Recordem que no poden ser visualitzades per una persona
  MD5_Final(digest, &state);
 
  //Generem una cadena amb el MD5, ara sí, en format llegible per a una persona
  md5=digestAMD5(digest);
 
  //Afegir caràcter de fi de cadena per a que el printf ens mostri correctament la nostra cadena
  md5[32]='\0';
  printf("El MD5 val: %s", md5);
  return 0;
}

Sembla i és una tonteria, però m'hi he trencat les banyes un parell de dies per a poder-ho fer servir...

Comparteix i gaudeix:
  • La Tafanera
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks

Leave a Reply