【Linux杂篇】经常登录Linux,用户密码背后的知识了解一下

一,用户密码存放在哪里?

说到这个问题,绝大部分的同学肯定都知道/etc/passwd这个文件,不错,这个文件里存储的就是用户名,密码等信息。
在这里插入图片描述

每一行都是一个account,每一行有7个信息,分别用 : 隔开,从左往右依次是:用户名:加密用户密码:用户id:组id:注释:工作目录:shell目录,这些信息被放在一个叫struct passwd的结构体中统一管理,struct passwd结构体包含以下信息:

struct passwd {
char *pw_name; /用户名/
char *pw_passwd; /加密用户密码/
int pw_uid; /用户id/
int pw_gid; /组id/
char *pw_gecos; /注释/
char *pw_dir; /用户主目录/
char *pw_shell; /shell目录/
};

但是通过查看/etc/passwd文件内容,发现加密密码一项都用了字符’x’表示。我们理解中的加密密码应该是一串看不出任何逻辑的字符才对,怎么会是一个‘x’呢?

二,/etc/shadow文件

上面一个内容中最后提出了一个疑惑,'x’的来由。这就是一个简单的历史遗留问题,早期的posix版本中’x’这个位置确实存放的是加密密码,也就是一串没有任何逻辑的字符,这串加密密码采用的是单向加密算法进行加密,也就是说无法通过反向破解得到密码,我想这也是早期会直接将加密密码放在/etc/passwd的原因吧。如果我们生的再早个十几年,就会直接在/etc/passwd中看到加密密码了。

但是/etc/passwd这个文件在同一超级管理员下的各个账户里是透明的,也就是说,谁都可以访问到/etc/passwd这个文件并且获取到那一串加密密码。这样有啥用,密码不还是单向加密的吗?尽管不可破解,但是仍然存在着根据用户的身份等信息推测密码经相同的加密处理后与原来的加密密码进行对比从而获取密码的风险。为了避免这种情况,现在的某些系统将加密密码存放在一个shadow(阴影)文件中,并且给这个文件设置为仅超级管理员可见,而/etc/passwd密码的位置仅仅用一个’x’意思一下。这个shadow文件就是**/etc/shadow**.

mbl:1Y/1ISiCx$S5mv/6lKRM1ZobXdP8629LsI2DsNWJpkAUFiO8PlZTN741DoyI6cvOFQVGluS/dF7tCadfACwhbfcFt5v0iK9Y8bp:18307:0:99999:7:::

左边第二个就是加密密码所在位置,1Y/1ISiCx$S5mv/6lKRM1ZobXdP8629LsI2DsNWJpkAUFiO8PlZTN741DoyI6cvOFQVGluS/dF7tCadfACwhbfcFt5v0iK9Y8bp盐值,从官方文档中我们可以知道用户密码经过了glibc中的crypt算法的处理,处理后会形成盐值后面的一串字符串,对于相同的密码,哈希算法加密出来的字符串也相同,因此,盐值的存在就是为了区分这些相同密码形成的相同加密码 同时也为破解增加了难度。
  /etc/shadow中的各个信息被struct spwd这个结构体管理。感兴趣可以了解一下。
  在这里插入图片描述
有了/etc/shadow,安全性就大大提高。想要获取加密密码?得先知道超级管理员密码。

如果可以成功的撸到crypt加密算法,下一节的内容就是crypt的算法实现了。

三,小福利

(1)先领略一下crypt的风采吧。

Python3:
在这里插入图片描述
C: 编译的时候要带上-lcrypt
在这里插入图片描述
(2)上面说到了/etc/passwd这个文件,自己编写个程序输出这里面的内容吧

#include <pwd.h>                                                              
  #include <cstring>
  #include <cstdio>
  void printPwRecord(){
      struct passwd *ptr = nullptr;
      setpwent();
      while((ptr = getpwent()) != nullptr){
          printf("%s:%s:%u:%u:%s:%s:%s\n", ptr->pw_name, ptr->pw_passwd, ptr->pw
                  , ptr->pw_dir, ptr->pw_shell);
      }
      endpwent();
  }
  int main(){
      printPwRecord();
  }

这段程序用到了三个函数,setpwent(); getpwent(); endpwent();

#include <sys/types.h>
#include <pwd.h>
struct passwd *getpwent(void);
void setpwent(void);
void endpwent(void);

这三个函数用于访问password file,比如/etc/passwd.
getpwent函数返回文件的的下一个记录项,setpwent函数定位到文件开始处,endpwent函数关闭这些文件。注意:在getpwent之前调用setpwent是自我保护性的措施,以便在调用者在此之前已经调用getpwent打开了有关文件的情况下,重新使他们定位到文件开始处。最后要调用endpwent关闭这些文件。

与passwd相关的还有getpwuid和getpwnam这两个函数,

#include <sys/types.h>
#include <pwd.h>
struct passwd *getpwnam(const char *name);
struct passwd *getpwuid(uid_t uid);

分别通过用户名/用户id获取该指定用户的struct passwd结构体,通过这个结构体可以访问该用户信息。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdnGuoYuying

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值