6
votes

I'm trying to understand how does Linux encrypt our password on the etc/shadow file, so I've dont a new virtual 'test' user to make some test:

user: newuser
password: usrpw123
Generated salt: Ii4CGbr7

So the OS makes me the following line on the etc/shadow file, using a SHA512 encryptation system ($6$): newuser:$6$Ii4CGbr7$IOua8/oPV79Yp.BwzpxlSHjmCvRfTomZ.bhEvjZV2x5qhrvk82lZVrEtWQQej2pOWMdN7hvKwNgvCXKFQm5CB/:15069:0:99999:7:::

Now, I take the SHA512 module from python and try this:

import hashlib
m = hashlib.sha512()
m.update('Ii4CGbr7'+'usrpw123')
print m.hexdigest

This gives me the following hash as a result: c73156daca3e31125ce457f1343201cc8a26400b2974440af2cc72687922b48b6631d21c186796ea2756ad987a996d2b261fe9ff3af4cc81e14c3029eac5df55

As you can see, it's different than the other one on the /etc/shadow file, and I dont know why if I'm using the same salt+password to generate the hash.
Can someone give me a hand and explain me more or less why this happens?

And also, why does the /etc/shadow files generates a hash with some dots (.)?
Thanks

3
Note that the hexdigest only includes [0-9a-f] characters, while the line in the shadow file is [0-9a-zA-Z/.], so the output formats are different to begin with...sarnold
SHA is not an encryption system. SHA is a hashing function. There's a big difference between the two.NullUserException

3 Answers

6
votes

The fields in /etc/shadow are not built or interpreted the way you think they are. You'll want to read the man page for details, but the most obvious difference is that it uses an unusual base64 encoding for both the salt and the hash.

6
votes

There is an algorithm for generating the password hashes found in /etc/shadow.

See this document for an explanation:
http://www.akkadia.org/drepper/SHA-crypt.txt

There's an implementation of this in python here:
http://packages.python.org/passlib/lib/passlib.hash.sha512_crypt.html

2
votes

I fell into the same trap as everything that I read lead me to believe you could retrieve the results the same way you have it written.

I was able to determine the password by using the salt and password using crypt.crypt()

import crypt
crypt.crypt(password, salt)

salt: $6$Ii4CGbr7 password: usrpw123

doesn't exactly use the hashlib library but it works.