http://qs321.pair.com?node_id=1190062

rdfield has asked for the wisdom of the Perl Monks concerning the following question:

I am maintaining a system which accepts pre-encrypted passwords from various sources. Recently I've been asked to support a system that generates hashed password like the following:
$1$ZD1qsc8PwUXqP9GihP+NHvWQ+FXap4Td0KWCMp8yrDQ=B71E718B3CC3262CC83F15B +B2A97A2C5429B2028D217A90D6D7E275E08F68A4AE69526B8FE05CFE06EAC5B8E0958 +B372FAC6040E36BEFB0F681ADE7F7E9861BE
which looks to me like an SHA512 hash (hex encoded) with a 32 byte salt (base64 encoded). I've tried reformatting it to crypt SHA512 standard using
use MIME::Base64 qw(encode_base64); my $hash = "B71E718B3CC3262CC83F15BB2A97A2C5429B2028D217A90D6D7E275E08 +F68A4AE69526B8FE05CFE06EAC5B8E0958B372FAC6040E36BEFB0F681ADE7F7E9861B +E"; my $b64hash = encode_base64(pack('H*', $hash)); my $salt = "ZD1qsc8PwUXqP9GihP+NHvWQ+FXap4Td0KWCMp8yrDQ="; my $saved = '$6$' . $salt . '$' . $b64hash; my $wild = "password"; print "OK" if crypt($wild, $saved) eq $saved;
but to no avail - the salt appears to be truncated:
$6$ZD1qsc8PwUXqP9Gi$D72oiWMfTm90ZFouvu.aU3C6UCOPGKyS2jbZSKefD8IGo13x49 +7sRFX8062y30pGIIc/KtC6aq9qui.FuKm6Y1
Then I tried Crypt::SaltedHash:
use Crypt::SaltedHash; use MIME::Base64 qw(decode_base64); my $password = "password"; my $crypt=Crypt::SaltedHash->new(algorithm=>'SHA-512', salt_len => 32, + salt => decode_base64("ZD1qsc8PwUXqP9GihP+NHvWQ+FXap4Td0KWCMp8yrDQ=" +)); $crypt->add($password); my $shash=$crypt->generate(); my $salt=$crypt->salt_hex(); print "Salt= $salt\n"; # to show that it is using the right salt print "hex encoded = " . unpack('H*',substr($shash,9)) . "\n"; # the substr is required as generate prepends {SSHA512}

but the hex encoded line doesn't match the one in the original string.

I'm wondering if the prepended $1$ is a clue? Maybe MD5 is involved somewhere along the line? Has anyone seen a hashed password like this before? And prepared to offer any hints?

Edited to include a real example

rdfield

Replies are listed 'Best First'.
Re: password encryption woes
by zentara (Archbishop) on May 11, 2017 at 16:51 UTC
    Hi, I'm just curious about your approach to the problem. From the first example hash, the $1$ indicates an MD5 hash, but there is no third $ to indicate where the salt ends. So why in your code do you assume the salt is everything up to the = sign?

    I'm not really a human, but I play one on earth. ..... an animated JAPH

      Looking at the data, the first part after the $1$ is in base64, and the rest of it is in hex. The amount of data in the hex string matches the size of an SHA512 digest.

      I have a number of examples of the same password being hashed with this function, and the size of the base64 part is always the same, but the value is different. When decoded, the string is exactly 32 bytes long.

      I have made the assumption that some random(?) data is being passed to an MD5 function, as this outputs 32 bytes. The $1$ would indicate, I think, that an md5 crypt function is being used to generate the salt, rather than md5 itself.

      Following on from this, my assumption is that this function used to return an MD5 hashed password, and has subsequently been upgraded to SHA512, but for whatever reason they didn't change the algorithm number, and didn't use the standard crypt(3) library.

      rdfield