Comment créer un hachage md5 d'une chaîne en C?

J'ai trouvé du code md5 composé des prototypes suivants...

J'ai essayé de savoir où je dois mettre la chaîne que je veux hacher, quelles fonctions je dois appeler, et où trouver la chaîne une fois qu'elle a été hachée. Je suis confus en ce qui concerne ce que les bits uint32 buf[4] et UInt32[2] sont dans la structure.

struct MD5Context {
    uint32 buf[4];
    uint32 bits[2];
    unsigned char in[64];
};

/*
 * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
 * initialization constants.
 */
void MD5Init(struct MD5Context *context);

/*
 * Update context to reflect the concatenation of another buffer full
 * of bytes.
 */
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len);

/*
 * Final wrapup - pad to 64-byte boundary with the bit pattern 
 * 1 0* (64-bit count of bits processed, MSB-first)
 */
void MD5Final(unsigned char digest[16], struct MD5Context *context);

/*
 * The core of the MD5 algorithm, this alters an existing MD5 hash to
 * reflect the addition of 16 longwords of new data.  MD5Update blocks
 * the data and converts bytes into longwords for this routine.
 */
void MD5Transform(uint32 buf[4], uint32 const in[16]);
31
c md5
demandé sur Takkun 2011-10-02 20:44:08

5 réponses

Je ne connais pas cette bibliothèque particulière, mais j'ai utilisé des appels très similaires. Donc, c'est ma meilleure estimation:

unsigned char digest[16];
const char* string = "Hello World";
struct MD5Context context;
MD5Init(&context);
MD5Update(&context, string, strlen(string));
MD5Final(digest, &context);

Cela vous donnera une représentation entière du hachage. Vous pouvez ensuite transformer cela en une représentation hexadécimale si vous voulez le passer sous forme de chaîne.

char md5string[33];
for(int i = 0; i < 16; ++i)
    sprintf(&md5string[i*2], "%02x", (unsigned int)digest[i]);
36
répondu Chris Eberle 2011-10-02 16:50:28

Voici un exemple complet:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(__APPLE__)
#  define COMMON_DIGEST_FOR_OPENSSL
#  include <CommonCrypto/CommonDigest.h>
#  define SHA1 CC_SHA1
#else
#  include <openssl/md5.h>
#endif

char *str2md5(const char *str, int length) {
    int n;
    MD5_CTX c;
    unsigned char digest[16];
    char *out = (char*)malloc(33);

    MD5_Init(&c);

    while (length > 0) {
        if (length > 512) {
            MD5_Update(&c, str, 512);
        } else {
            MD5_Update(&c, str, length);
        }
        length -= 512;
        str += 512;
    }

    MD5_Final(digest, &c);

    for (n = 0; n < 16; ++n) {
        snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]);
    }

    return out;
}

    int main(int argc, char **argv) {
        char *output = str2md5("hello", strlen("hello"));
        printf("%s\n", output);
        free(output);
        return 0;
    }
31
répondu todd 2011-12-05 18:06:38

Comme d'autres réponses l'ont mentionné, les appels suivants calculeront le hachage:

MD5Context md5;
MD5Init(&md5);
MD5Update(&md5, data, datalen);
MD5Final(digest, &md5);

Le but de le diviser en autant de fonctions est de vous permettre de diffuser de grands ensembles de données.

Par exemple, si vous hachez un fichier de 10 Go et qu'il ne rentre pas dans la ram, voici comment vous le feriez. Vous liriez le fichier en petits morceaux et appelez MD5Update sur eux.

MD5Context md5;
MD5Init(&md5);

fread(/* Read a block into data. */)
MD5Update(&md5, data, datalen);

fread(/* Read the next block into data. */)
MD5Update(&md5, data, datalen);

fread(/* Read the next block into data. */)
MD5Update(&md5, data, datalen);

...

//  Now finish to get the final hash value.
MD5Final(digest, &md5);
7
répondu Mysticial 2011-10-02 16:58:05

, Pour être honnête, les commentaires accompagnant les prototypes semblent assez claires. Quelque chose comme ça devrait faire l'affaire:

void compute_md5(char *str, unsigned char digest[16]) {
    MD5Context ctx;
    MD5Init(&ctx);
    MD5Update(&ctx, str, strlen(str));
    MD5Final(digest, &ctx);
}

str est une chaîne C dont vous voulez le hachage, et digest est le résumé MD5 résultant.

5
répondu NPE 2011-10-02 16:46:33

, Il semblerait que vous devriez

  • Créez un struct MD5context et passez-le à MD5Init pour l'obtenir dans une condition de départ appropriée
  • Appel de MD5Update avec le contexte et vos données
  • appelez MD5Final pour obtenir le hachage résultant

Ces trois fonctions et la définition de la structure font une belle interface abstraite à l'algorithme de hachage. Je ne sais pas pourquoi on vous a montré la fonction de transformation de base dans cet en-tête car vous ne devriez probablement pas interagir directement avec elle.

Le l'auteur aurait pu faire un peu plus de cache d'implémentation en faisant de la structure un type abstrait, mais alors vous auriez été obligé d'allouer la structure sur le tas à chaque fois (par opposition à maintenant où vous pouvez le mettre sur la pile si vous le désirez).

1
répondu dmckee 2011-10-02 16:53:43