linux c 验证 linux 用户密码

linux 用户加密后的密码是存放在 /etc/shadow 文件中。 shadow 文件的说明见以下链接:http://blog.csdn.net/u011641885/article/details/46681697


    最初linux将用户的密码通过某种one-way function得到一个散列(加密)后的字符串,并存储该字符串在密码文件中,但这种方式易遭受字典攻击,攻击者只有准备好字典,使用相同的one-way function计算出对应的值,逐个对比就ok就可以攻破。
    为了提高安全性,引入salt,所谓的salt,即为一个随机数,引入的时候为一个2字符的字符串(从[A-Za-z0-9./]共64个字符选取,后来salt扩展到最多12个字符),当用户设置密码时,会随机生成一个salt,与用户的密码一起加密,得到一个加密的字符串(salt以明文形式包含在该字符串中),存储到密码文件中,这样就将攻击的难度扩大了64*64即4096倍。
    crypt将用户的key和salt一起适应某种算法进行加密(散列)

 char *crypt(const char *key, const char *salt);

    crypt中可以使用多种加密(散列)机制,包括最初的DES,还有后来为提高安全性引入的md5,blowfish,sha-256,sha-512.
    crypt为支持不同的方式,将salt进行格式化,格式为:
    $id$salt$encoded (这也是保存在shadow文件中的格式)
这里不同id代表不同的算法,不同算法salt的长度也不同。
  id      Method      实际加密后的密码长度 
  1    MD5(12 个 salt 字符)        22
  2a    Blowfish   只在某些发行版中支持  
  5    SHA-256 (12 个 salt 字符)          43
  6    SHA-512 (12 个 salt 字符)        86
    最初的DES方式的salt为2个字符(A-Za-z0-9/+)提供了64*64=4096种可能性。然后将用户key与salt拼接成一个新的字符串,用这个字符串作为密钥对某个原始串(通常为全0)进行DES加密,得到11个字符,然后将这11个字符接到salt后面即为用户加密后的密码。


使用 C 语言验证某个用户的密码:


源码如下:

#include <stdio.h>
#include <string.h>
#include <shadow.h>
#include <unistd.h>
int main(int argc, char **argv)
{
       struct spwd  *sp;
       sp = getspnam(argv[1]);
       if(sp == NULL)
       {
              printf("get spentry error\n");
              return -1;
       }
 
       if(strcmp(sp->sp_pwdp, (char*)crypt(argv[2], sp->sp_pwdp)) == 0) 
      {
              printf("yes\n");
       }
       else
       {
              printf("no\n");
       }
       return 0; 
}

注意:执行的时候需要 root 权限。。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章