Search code examples
cunixhashcrypt

crypt() not returning standard MD5 Hash?


I'm trying to use the crypt() function found in <crypt.h> in C, and when I attempt to hash a string in MD5 for example, it returns something different than a standard MD5 hash would produce from a tool such as md5sum. Example/Proof:

hash.c:

#include <stdio.h>
#include <crypt.h>

#define MD5 "$1$"

int main() {

        const char string[] = "helloworld";
        char * hash = crypt(string, MD5);

        printf("%s\n",hash);

        return 0;
}

I compile with gcc -o hash hash.c -lcrypt and run:

./hash
$1$$edK86ZB1Vvaz2eneY.itb.

From my knowledge of UNIX systems, the format of the output of crypt matches the password format of UNIX users whereas the first part is the hash ID/type, the second part is the salt and the third is the actual hash - $id$salt$hash. Yet the ACTUAL standard MD5 hash of helloworld is fc5e038d38a57032085441e7fe7010b0. Is there any way to produce this hash using crypt()? Many thanks!


Solution

  • The string returned by the glibc implementation of crypt() is not just a simple hash of the salt + password encoded into base 16.

    If you look at the source code of the MD5 version, you'll see among other things a loop that takes a previous MD5 hash and hashes that, for one thousand repetitions. Then it's turned into a string with repeated use of a function named __b64_from_24bit() that encodes 3 bytes of the final MD5 hash at a time (not in linear order) into what I assume is base 64.

    This is why what you see looks nothing like the output of md5sum or the like.