crypt函数加密验证

#include<stdio.h>
#include<unistd.h>
#include<shadow.h>
#include<string.h>
#include<stdlib.h>
void get_salt(char *salt,char *passwd)
{
        int i,j;
        for(i=0,j=0;passwd[i]&&j!=3;++i) //i=11的时候passwd[i]=='$',出for循环的时候i=12
        {
                if(passwd[i]=='$')
                        j++;
        }
        strncpy(salt,passwd,i-1);   //ncpy拷贝i个,源代码写的循环是<n
}
int main()
{
        struct spwd *sp;
        char *passwd;
        char *name;
        char salt[512]={0};
        //获得输入的用户名和密码;
        //char *getpass(const char *prompt);   //函数原型
        name = getpass("please input usrname:");
        passwd = getpass("please input passwd:");
        //struct spwd *getspnam(const char *name);   //函数原型
        sp = getspnam(name); 
        if(NULL==sp)
        {
                perror("getspnam");
                return -1;
        }
        get_salt(salt,sp->sp_pwdp);    //通过加密后的字符串,取出id和salt字符串
        printf("%s\n",salt);
        //char *crypt(const char *key, const char *salt);
        if( ( strcmp(sp->sp_pwdp,crypt( passwd,salt)) )==0)
                printf("success!\n");
        else
                printf("fail!\n");
        return 0;
}
wPveOSKeq+mmgAAAABJRU5ErkJggg== 
//linux密码验证


cat /etc/shadow   
meihao: $1$qDku/Q8E$tfeCg6yg8D3bZ8hzk8V2y/:17354:0:99999:7:::




对于linux的登陆验证我想大家可能都知道是将输入的密码进行相应编码加密后与/etc/shadow文件中对应的密码部分进行比较,如果相同则验证通过,如果不同则表明密码错误,但是问题是我们要如何将用户输入的密码加密然后进行比较。

为了提高安全性,Linux引入了salt,所谓salt即为一个随机数,引入的时候为一个12bit的数值,当用户设置密码时,会随机生成一个salt与用户的密码一起加密,得到一个加密的字符串(salt以明文形式包含在该字符中),存储到密码文件中。crypt函数可以将用户输入的密码和salt一起适应某种算法进行加密,该加密后的字符串就是我们需要的与密码文件中密码对比的加密字符串。
crypt为支持不同的方式将salt格式化为
$id$salt$encode
其中id代表不同的算法
              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)   当前我们Linux采用的加密算法

这样我们就可以利用crypt函数将用户输入的字符加密,然后与密码文件中的密码进行对比了,有一个函数getspnam可以根据用户名从/etc/shadow中得到密码,函数返回的数据结构
struct spwd {
               char *sp_namp;     /* Login name */
               char *sp_pwdp;     /* Encrypted password */
               long  sp_lstchg;   /* Date of last change (measured
                                     in days since 1970-01-01 00:00:00 +0000 (UTC)) */
               long  sp_min;      /* Min # of days between changes */
               long  sp_max;      /* Max # of days between changes */
               long  sp_warn;     /* # of days before password expires
                                     to warn user to change it */
               long  sp_inact;    /* # of days after password expires
                                     until account is disabled */
               long  sp_expire;   /* Date when account expires (measured
                                     in days since 1970-01-01 00:00:00 +0000 (UTC)) */
               unsigned long sp_flag;  /* Reserved */
           };
我们现在创建一个test用户,并将密码设置为1234来做个测试看一下
这是创建之后从/etc/shadow中取出来的密码部分
$6$qOrvsN41$gGlv8z7P1sAKuyaTAY03AvCn9/Z6Ygc4DJ9Uwe0RVzNAI6TQsTfsdihPnIh3lSZV2C02HjW.9bvJNdep3k.ER.
可以看到这里的salt为$6$qOrvsN41





转载于:https://www.cnblogs.com/meihao1203/p/8685610.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值