DEV Community

BC
BC

Posted on • Edited on

How Linux stores user's password - Linux Tips

In Linux, user's password is saved in /etc/shadow file, if you take a look the content, it looks like this:

root:$6$MksUWINOmX.9ZXyP$yjO8RvJj5i9.G/mOx7ZA3npdX05iv5Z07k3zI/02LMBjPE01e8hUlVhMNNpzRIWG1n0n6flWZGgW2T/LsZGRT0:17885:0:99999:7:::
Enter fullscreen mode Exit fullscreen mode

If we split this string by ":", we will get several fields:

  1. root
  2. $6$MksUWINOmX.9ZXyP$yjO8RvJj5i...ZGRT0
  3. ...

Here we just focus on the first 2 fields: The first one is username, the second one is hashed password.

The hashed password, $6$MksUWINOmX.9ZXyP$yjO8RvJj5i...ZGRT0 in this case, contains 3 parts, the format is:

$hash-method-id$salt$hashed-string
Enter fullscreen mode Exit fullscreen mode

So in our case, if we separated the above string by "$":

  • 6 -> the hash method id
  • MksUWINOmX.9ZXyP -> salt
  • yjO8RvJj5i...ZGRT0 -> hashed-string

6 is the hash method id, Linux supports multiple hash methods:

  • 1: MD5
  • 2a: Blowfish (not in mainline glibc; added in some Linux distributions)
  • 5: SHA-256 (since glibc 2.7)
  • 6: SHA-512 (since glibc 2.7)

So in our example, now we know Linux hashed our password with the salt with SHA-512 algorithm, then save it in /etc/shadow file.

Verify with Python

Python has a crypt library for this hashing.

To generate a random salt for the hashing method SHA-512:

>>> import crypt
>>> crypt.mksalt(crypt.METHOD_SHA512)
'$6$nPDcj0JFDC76QDxe'
>>> crypt.mksalt(crypt.METHOD_SHA512)
'$6$z5XUE0nOLtk8uTEn'
>>> crypt.mksalt(crypt.METHOD_SHA512)
'$6$Qu6XnlFT16QUTfiQ'
Enter fullscreen mode Exit fullscreen mode

To verify the hashed password in our example, we can use crypt.crypt to calculate the hashed value for our plain password with the salt ("myloginpwd" is my plain password here):

>>> import crypt
>>> crypt.crypt("myloginpwd", "$6$MksUWINOmX.9ZXyP")
'$6$MksUWINOmX.9ZXyP$yjO8RvJj5i9.G/mOx7ZA3npdX05iv5Z07k3zI/02LMBjPE01e8hUlVhMNNpzRIWG1n0n6flWZGgW2T/LsZGRT0'
Enter fullscreen mode Exit fullscreen mode

We can see this hashed string is the same as the one saved in /etc/shadow file.

Reference

Top comments (5)

Collapse
 
patriziobruno profile image
Patrizio Bruno

Nice article for understanding Linux's inner gears. But if serious about accessing /etc/passwd or /etc/shadow from a python script, it's best to use python's spwd module

Collapse
 
bitecode profile image
BC

Nice, thank you for sharing, Patrizio.
Also the pwd, grp, getpass lib may help:

A good example here: docs.python.org/3/library/crypt.ht...

Collapse
 
dantehemerson profile image
Dante Calderón

Thanks for the tip, these are useful for know more linux

Collapse
 
apsknight profile image
Aman Pratap Singh

Just curious, what'll happen if I delete or modify /etc/passwd file?

Collapse
 
bitecode profile image
BC • Edited

Hi Aman, that shouldn't be too hard to test, for example, if you replace the string in /etc/shadow for the root user with a new password "123456", then save it.

>>> import crypt
>>> crypt.crypt("123456", "$6$Y8f56LIJccEhGpMA")
'$6$Y8f56LIJccEhGpMA$7vWlVx5emkzuqeBdRgb4nqmHek6N/ZbWGIEqLbQh3k1.lf0agvBRljdpRooL8UhCRJse3U6RcVznFe8o0i0gm1'

Then try to su again, you will find your old password for root won't work any more, instead, you will need to type the new password "123456".

Same for delete, if you delete or rename /etc/shadow to other file, you won't be able to su, since the system now can't find the password to verify