C/C++: calculando hash MD5 usando a biblioteca do OpenSSL

C/C++

Obter o hash MD5 de uma string é uma tarefa bem simples em algumas linguagens de mais alto nível, como Python, Ruby ou PHP. Porém, em C e C++ não é tão simples. Sem o auxílio de uma biblioteca externa, não podemos calcular hashes, como MD5 ou SHA-1 (exceto se você implementar esses algoritmos, é claro).

Mostrarei adiante como calcular o hash MD5 de uma string, utilizando a biblioteca OpenSSL, disponível nos sistemas Linux e Unix-Like (em Mac OS X também funciona, apesar de aparecerem warnings dizendo que as funções da OpenSSL são obsoletas).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
 
/**
 * Função que retorna o hash MD5 de uma string
 *
 * @param input String cujo MD5 queremos calcular
 * @param output String onde será escrito o MD5 (deve estar previamente alocada)
 */
char * md5FromString( char *input, char *output )
{
    EVP_MD_CTX mdctx;
    const EVP_MD *md;
    unsigned int output_len, i;
    unsigned char uOutput[EVP_MAX_MD_SIZE];
 
    /* Initialize digests table */
    OpenSSL_add_all_digests();
 
    /* You can pass the name of another algorithm supported by your version of OpenSSL here */
    /* For instance, MD2, MD4, SHA1, RIPEMD160 etc. Check the OpenSSL documentation for details */
    md = EVP_get_digestbyname( "MD5" );
 
    if ( ! md )
    {
        printf( "Unable to init MD5 digest\n" );
        exit( 1 );
    }
 
    EVP_MD_CTX_init( &mdctx );
    EVP_DigestInit_ex( &mdctx, md, NULL );
    EVP_DigestUpdate( &mdctx, input, strlen( input ) );
 
    EVP_DigestFinal_ex( &mdctx, uOutput, &output_len );
    EVP_MD_CTX_cleanup( &mdctx );
 
    // zera a string antes de começar a concatenação
    strcpy( output, "" );
    for(i = 0; i < output_len; i++)
    {
        sprintf( output, "%s%02x", output, uOutput[i] );
    }
 
    return output;
}
 
 
main(int argc, char *argv[])
{
    char output[33]; // 32 caracteres mais um para o \0
 
    if ( argc != 2 )
    {
        fprintf( stderr, "Erro. Uso: %s \n", argv[0] );
        exit( 1 );
    }
 
    printf( "MD5( '%s' ) = %s\n", argv[1], md5FromString( argv[1], output ) );
 
    return 0;
}

Esse código foi adaptado a partir deste post, once encontrei uma forma simples e objetiva de calcular o hash.

Para compilar, é necessário linkar com a biblioteca do OpenSSL, com a opção -lcrypto, conforme o exemplo abaixo:

gcc md5.cpp  -lcrypto -o md5

Para executar, passe como parâmetro a string cujo MD5 deseja-se calcular:

$ ./md5 "string a ser convertida em hash"

Espero que tenham gostado da dica. :)

Dicas de Livros

O livro escrito pelos criadores da linguagem C: C – a Linguagem de Programacao Padrao Ansi – Kernighan, Brian / Ritchie, Dennis M
C – Completo e Total – Schildt, Herbert
C Como Programar 6 Edicao – Paul; Deitel Harvey Deitel
Linguagem C – Luís Damas

The following two tabs change content below.
Graduado em Ciência da Computação, pela Universidade Federal do Paraná (UFPR), é desenvolvedor de software desde 2008, com foco em Desenvolvimento Web com PHP.
  • Ranyer Lopes

    Olá Beraldo,
    Eu queria saber se você implementou o código em c do OpenSSL, ou apenas incluiu ele?
    Já que ele é nativo do Linux.

    Aguardo resposta!

    • Olá. Não implementei, não. Só adicionei a biblioteca nativa do C

      • Ranyer Lopes

        Olá novamente Beraldo,

        Tenho um questionamento:
        Eu trabalho com um algoritmo simétrica baseando em cifras de bloco.
        A questão é, ele funciona, criptografa e decriptografa, mas se eu quiser implementar o SSL nele, eu posso apenas adicionar os comando da biblioteca OpenSSL no meu código?