理解linux 密码存储
1. 传统上,linux把加密(哈希)的密码保存在/etc/passwd文件中,passwd文件的格式如下:
smithj:x:561:561:Joe Smith:/home/smithj:/bin/bash
共7个字段,由":"分隔, 各字段的含义如下:
- smithj, Username, up to 8 characters. Case-sensitive, usually all lowercase
- 加密后的密码,空表示没有密码;“x"表示密码保存在/etc/shadow文件中。
- Numeric user id. This is assigned by the ``adduser'' script. Unix uses this field, plus the following group field, to identify which files belong to the user.
- Numeric group id. Red Hat uses group id's in a fairly unique manner for enhanced file security. Usually the group id will match the user id.
- Full name of user. I'm not sure what the maximum length for this field is, but try to keep it reasonable (under 30 characters).
- User's home directory. Usually /home/username (eg. /home/smithj). All user's personal files, web pages, mail forwarding, etc. will be stored here.
- 用户的shell. Often set to ``/bin/bash'' to provide access to the bash shell
2. /etc/shadow文件详解
shadow文件的每一行定义一个用户,共九个字段,格式如下:
{用户名}:{加密后的口令密码}:{口令最后修改时间距原点(1970-1-1)的天数}:{口令最小修改间隔(防止修改口令,如果时限未到,将恢复至旧口令):{口令最大修改间隔}:{口令失效前的警告天数}:{账户不活动天数}:{账号失效天数}:{保留}
例如:
root:$6$4rSdQWBy$970A61Zc6.5b1Ioh2Sl3dj/EbpKChilvqPsQz3h78YhcYnVoPQ9xXZeABlRLpfFsgTX0dlegSpC56LLqCPje41:0:0:99999:7:::
- Username, up to 8 characters. Case-sensitive, usually all lowercase. A direct match to the username in the /etc/passwd file.
- Password, 13 character encrypted. A blank entry (eg. ::) indicates a password is not required to log in (usually a bad idea), and a ``*'' entry (eg. :*:) indicates the account has been disabled.
- The number of days (since January 1, 1970) since the password was last changed.
- The number of days before password may be changed (0 indicates it may be changed at any time)
- The number of days after which password must be changed (99999 indicates user can keep his or her password unchanged for many, many years)
- The number of days to warn user of an expiring password (7 for a full week)
- The number of days after password expires that account is disabled
- The number of days since January 1, 1970 that an account has been disabled
- A reserved field for possible future use
3. 密码字段的格式:
密码字段分为三个部分,由$分隔:
$加密算法代号$盐值$密文
- 加密算法:
- $1$ is MD5
- $2a$ is Blowfish
- $2y$ is Blowfish
- $5$ is SHA-256
- $6$ is SHA-512
- 盐值
盐值的位数与加密算法有关,以SHA-512为例,盐值是一个base64的随机串,串的长度是8~16的随机数。
linux中加密由crypt()函数实现,crypt()会调用crypt_make_salt()函数生成盐值。盐值长度是一个个随机数,由shadow_random(8,16)函数产生。因此,linux中加密密码的盐值的位数由程序自动生成,是不可配的。除非修改源码。
crypt_make_salt()--->gensalt(salt_size)---->l64a(random())生成base64编码的,长度为salt_size的盐值字符串。
- 密文
盐值+密码(明文)通过加密算法得到的字符串(base64)。