linux是如何进行密码管理的

linux是如何进行密码管理的

Posted by lwk on April 24, 2020

对于linux运维人员来说,大部分人应该都知道/etc/passwd和/etc/shadow两个文件,分别存储的是linux用户的用户名以及密码等数据。实际,大部分情况下/etc/shadow才是存放密码的文件,而不是/etc/passwd。

先看下/etc/passwd文件的格式,以下截图为/etc/passwd部分内容:

image 再看下/etc/shadow文件内容,以下截图为/etc/shadow部分内容:

image 重点看maun:后面的三个$内容,即$1$DW$VL**

这三个$分别对应的是:加密算法、salt内容、加密后的密码。

目前支持的加密算法有三种:分别是MD5、SHA256和SHA512,分别对应的是1、5和6

注:实际这里不应该叫加密算法,因为MD5只是一种编码格式。但shadow源码里的函数命名就是encrypt(加密),所以这里就认为它是加密算法吧。

本文将通过修改用户密码来阐述linux的密码管理。

Linux的密码管理源码是shadow,git地址是:https://github.com/shadow-maint/shadow

Clone下来,main函数在src/passwd.c,从main函数入手: image

image Passwd数据结构定义在glibc的pwd/pwd.h文件中,数据结构如下: image

接下来看下new_password函数。 image

image image

image

image 我们看下/etc/login.defs的内容,部分内容截图如下: image 因此,def_find函数根据ENCRYPT_METHOD查找对应的值就是MD5,因此使用MD5进行密码的加密。

注意:开发测试机上的ENCRYPT_METHOD配置都是MD5,但线上环境配置的都是SHA512 image image

确定加密算法之后,接下来就是生成salt了,健壮的加密算法一般都会加盐。 image image

主要看gensalt函数,上面获取method的已经在上面分析过。 image

image

目前有了明文密码和salt之后,接下来就是进行加密。

image

image

调用crypt函数,crypt函数在glibc代码里定义 image

image 从上面的调用可以知道,传给crypt函数的两个参数值分别是:pass,$1$**$*

因此,crypt函数匹配到第一个if语句为真,即MD5加密方式,继续调用__md5_crypt(key,salt)函数。

image

__md5_crypt_r函数就是将pass和salt进行一系列的转换后,输出加密串,而不是简单地返回hash值。

生成加密串后,将加密串赋给字符数组crypt_passwd image 得到加密串之后,就更新/etc/shadow文件,过程结束。 image