How is my password stored in Linux?

Background

People that use Linux on a daily basis probably are completely oblivious to the actual mechanisms being used to store their passwords safely and securely on a given Linux system. Oh they might guess that their password is stored in the /etc/passwd file (they’d be wrong by the way) but most probably never even gave it a passing thought. So I thought I’d take the opportunity to shed some light on how Linux systems “stash” your precious password away.

Solution

So if your password isn’t actually stored in the /etc/passwd file then where does it get stored?

Answer: the /etc/shadow file.

This file is where all the keys to each user’s account are kept for safe keeping. Obviously only the root user can peer inside this file so all the commands we’ll be dealing with in this post, it should be assumed that you’ll need to either be root, or use sudo to run.

/etc/shadow

A typical /etc/shadow entry:

1
root:$6$bbmDJwcZHy5bgEDz$kFO.W/T7nUqcszZWl5RglxoDDAcDxevWpHVfN3v3f.Cx2ZeMcn5PX23VvnnkgtNWZf8hYtqsL0pPkZqyj50NY/:14362:0:33333:7:::

NOTE1: Don’t get too excited, the above isn’t really my entry, I made this one up.
NOTE2: Each field is separated by a colon (:) & we’re only concerned with the first two columns!

dissecting the hash

The key pieces to notice in that line of what looks like gibberish is the following:

  • The first column, root is the user whom this entry belongs to from the /etc/passwd file.
  • The second column, $6$..... is essentially the user’s hashed password.

Taking the second column apart further you should start to notice that’s it’s not complete gibberish after all.

For example:

  • the first couple of characters, $6$, is a mark that tells the system what type of hashing was used to hash the password.
  • The text between the next set of dollar signs, $bbmDJwcZHy5bgEDz$, is the actual salt that was used to hash your password.
  • Everything else after, is your password + salt hashed using whatever hash function was specified at the beginning, $6$, in our example here.

Specifically if you look at the man page for the crypt command, man 3 crypt there is a section that discusses what the $6$ notation means:

So $5$salt$encrypted is an SHA-256 encoded password and $6$salt$encrypted is an SHA-512 encoded one.

NOTE: So in our case the password + salt is being hashed using the SHA-512 scheme.

design details

For reference purposes here’s the rest of that excerpt from the crypt man page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
If salt is a character string starting with the characters "$id$" followed by a
string terminated by "$":
 
       $id$salt$encrypted
 
then instead of using the DES machine, id identifies the encryption method used
and this then determines how the rest of the password string is interpreted.
The following values of id are supported:
 
       ID  | Method
       ─────────────────────────────────────────────────────────
       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 $5$salt$encrypted is an SHA-256 encoded password and $6$salt$encrypted is an
SHA-512 encoded one.
 
"salt" stands for the up to 16 characters following "$id$" in the salt. The
encrypted part of the password string is  the actual computed password. The
size of this string is fixed:
 
MD5     | 22 characters
SHA-256 | 43 characters
SHA-512 | 86 characters
 
The characters in "salt" and "encrypted" are drawn from the set [a–zA–Z0–9./].
In the MD5 and SHA implementations the entire key is significant (instead of
only the first 8 bytes in DES).
Now what?

So by now you’re probably saying to yourself. OK, big deal, my password is hashed with some salt and stored in /etc/shadow. What else?

generating the hash manually using mkpasswd

For starters you can generate the $6$... string yourself manually using the mkpasswd command:

1
2
$ mkpasswd -m sha-512 password saltsalt
$6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/

In the above command we’re specifying that we want to use the SHA-512 hash, our password is the string password and our salt string is saltsalt. As before we can see in our resulting string the following components:

  • $6$ – which hash function was used
  • saltsalt – the string “saltsalt” was used
  • qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/ – password + salt hashed using SHA-512
generating the hash manually using Python

I came across the following nice Python one-liner that effectively does the same thing as the mkpasswd command discussed above.

1
2
3
$ python -c "import crypt, getpass, pwd; \
             print crypt.crypt('password', '\$6\$saltsalt\$')"
$6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
generating the hash manually using Perl
1
2
$ perl -e 'print crypt("password","\$6\$saltsalt\$") . "\n"'
$6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
authconfig

Before I wrap up I thought I’d mention one final tool authconfig that’s included on Red Hat distros such as Fedora, CentOS, and RHEL. This tool allows you to change what hash algorithm is being used on a particular system. The command to change a system to use SHA-512 would be as follows:

1
authconfig –passalgo sha512 –update

See the man page for authconfig for more details.

conclusions

And with that you are now a little more in the know as to how Linux systems take your password and store them in the /etc/shadow file.

References

links
This entry was posted in encryption, linux, passwords, Security, SHA-512, shadow, Syndicated, sysadmin, tutorials. Bookmark the permalink.

Comments are closed.