Openssh programatic MD5 hash digest not matching the shell command output

Viewed 147

I'm experimenting with MD5 hashes using the openssl library. When I run the code below:

std::string test("123");    // salt
test.append("TestPhrase");  // password
unsigned char buffer[test.size()];
strcpy((char *)buffer, test.c_str());
unsigned char digest[MD5_DIGEST_LENGTH];
MD5_CTX(ctx);
MD5_Init(&ctx);
MD5_Update(&ctx, buffer, test.size());
for(int i = 0; i < MD5_DIGEST_LENGTH; ++i)
{
  printf("%02x", digest[i]);
}
  putchar('\n');

I'm consistently getting a hash value of:

ad9c231a6c45cccecc3b558545e7fd75

I used the Openssl documentation as a reference and looked around to see how others are doing it. It certainly is not the cleanest code, but I don't believe this is incorrect. However, when I try to run the openssl command, which uses the same library and what I thought was the same hashing function I get a completely different value:

openssl passwd -quiet -salt "123" -1 "TestPhrase"

$1$123$PWLKL9JcywaTF.UrzC7ov/

I have also tried the Apache variant algorithm -apr1 which also generates a non-matching hash. I'm assuming it must be the way I'm displaying the bits to the screen, but this seems to be how every post I have found does it. What am I missing?

2 Answers

The documentation for openssl passwd says for the -1 option: Use the MD5 based BSD password algorithm 1. That is not the same thing as Use MD5, what you are doing. Just taking the md5 would result in passwords that are fairly easy to crack.

You can glance at the md5crypt function implementation in the openssl passwd tool to see that the actual process is much more involved. For example it includes a loop that repeetitively (1000x) invokes EVP_DigestUpdate()

It is surprisingly hard to find a proper description of that MD5 based BSD password algorithm 1, but this blog post does a good job: Password hashing with MD5-crypt in relation to MD5


If you do want to reproduce your current result with an OpenSSL tool, you could use dgst like this:

$ printf 123TestPhrase | openssl dgst -md5   
ad9c231a6c45cccecc3b558545e7fd75

ad9c231a6c45cccecc3b558545e7fd75

is just

PWLKL9JcywaTF.UrzC7ov/

, but in Hexadecimal instead of Base 64.

Related