近期做EasyCluster,需要创建用户,要求在Linux上能创建一个用户帐号,很自然想到了后台程序调用useradd命令行来完成,但众所周 知,密码是个麻烦事。查看了 useradd的手册,有个-p password 选项可以在创建的时候就指定密码,但要求这里的密码是已经加过密的,这就要求用crypt函数进行加密,然后再放入命令行。故测试了一下,写了一段测试代 码,用来生成密码:

Code: Select all
#define _XOPEN_SOURCE
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    char key[] = "666666";
    printf("encrypted password is: %s\n", crypt(key, "3a"));
    return 0;
}

这 里就能生成666666的密码。要注意的是,首先必须定义 _XOPEN_SOURCE ,这是crypt的手册中要求的;第二,crypt函数的第一个参数是明文密码,第二个参数叫做“salt”,其实就是一个加密的密钥,有两个字符组成, 字符的取值可以是“a-zA-Z0-9./” 这些,具体请看手册。

然后用 useradd -p <encrypted password> <username> 就可以生成一个我们指定密码的帐号了。

CAUTION: 用户登录和上述过程是一个相反的过程,但难度在于不知道salt。这里不同的加密方法有不同的规则,比如某些加密方法,加密出来的密文的头两个字母就是 salt,有些则不是。在所有的机密方法上,glibc提供了crypt这个调用,屏蔽了多种加密算法的复杂性,这应该就是Linux的PAM机制。所 以,用户登录的时候,首先要根据加密方法在密文中取出salt,然后调用crypt生成密文,再对比,即可!一种加密方法不行,再试第二种。这里有我们 EasyCluster的用户登录后台验证的代码,在RedHat和SuSE(SuSE和RedHat的加密方法就不同,不过对于创建密码来说,两者都是 一样的,都是调用crypt嘛,如上所述)中都试验通过了:

Code: Select all
#define _XOPEN_SOURCE
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

#include "easy_s.h"
#include "common.h"

//  you need link your object file like this:
//                        gcc -o xx  xxx.c  -lcrypt
//int authenticate_user(char *username, char *key);

int authenticate_user(char *username, char *key)
{
    const int buffer_len = 512;
    const char filename[50] = "/etc/shadow";
    char *dataline = (char *)malloc(buffer_len);
    if (dataline == NULL){
        message_log("authenticate_user() error: failed to allocate space for user data buffer.");
        return -2;
    }
   
    FILE *fp = fopen(filename, "r");
    if (fp == NULL){
        free(dataline);
        //fprintf(stderr, "failed to open user account file.\n");
        return -1;
    }

while (fgets(dataline, buffer_len, fp)){
        if (strstr(dataline, username)){   
            /*
    char *crypt(const char *key, const char *salt).
     If  salt is a character string starting with the three characters "$1$"
     followed by at most eight characters, and optionally  terminated 
     by  "$",  then instead of using the DES machine, the glibc crypt
       function uses an MD5-based algorithm,  and  outputs  up  to  34  bytes,
       namely  "$1$<string>$", where "<string>" stands for the up to 8 charac-
       ters following "$1$" in the salt, followed by 22 bytes chosen from  the
       set [a-zA-Z0-9./].
            */
            char *line = strstr(dataline, "$1$");
            char *t;
            /*if ((line == NULL) || (strlen(line) < 4)){
                free(dataline);
                fclose(fp);
                return -4;
            }
            */

if (line == NULL ){
                line = strchr(dataline, ':');
                if (line == NULL){
                    free(dataline);
                    fclose(fp);
                    return -4;
                }
                t = strchr((line+1), ':');           
                if (t == NULL){
                    free(dataline);
                    fclose(fp);
                    return -4;
                }
                *t = '\0';
                char salt_1[16];
                salt_1[0] = line[1];salt_1[1] = line[2];salt_1[2] = '\0';
                char *pass = crypt(key, salt_1);
                if (pass == NULL){
                    free(dataline);
                    fclose(fp);
                    return -4;
                }
                if (strcmp((line+1), pass) == 0){
                    free(dataline);
                    fclose(fp);
                    return 0;
                }else{
                    free(dataline);
                    fclose(fp);
                    return -5;
                }
            }
            if (strlen(line) < 4){
                free(dataline);
                fclose(fp);
                return -4;
            }
           
            t =strstr((line+3), ":");
            if (t == NULL){
                free(dataline);
                fclose(fp);
                return -4;
            }
            t[0] = '\0';
            t = strstr((line+3), "$");
            if (t == NULL){
                free(dataline);
                fclose(fp);
                return -4;
            }
           
            char salt[50];
            memcpy(salt, line, t-line+1);
            char *encrypt_str = crypt(key, salt);
            if (encrypt_str == NULL){
                free(dataline);
                fclose(fp);
                return -5;
            }
            if (strcmp(encrypt_str, line) == 0){
                free(dataline);
                fclose(fp);
                return 0;
            }
        }
    }

free(dataline);
    fclose(fp);
    return -4;
}

同上,使用usermod命令的-p选项就可以修改用户密码。如:usermod -p <encrypted password> username 即可

转载于:https://www.cnblogs.com/super119/archive/2011/04/05/2005605.html

使用crypt生成用户密码-Tested on RedHat SuSE Platform相关推荐

  1. centos 欢迎字符串_Centos系统用户密码字符串生成命令-shadow

    这两天在看puppet,准备用这个管理我手下系统的用户添加分配与删除工作,不过每次要是都用系统的passwd命令生成用户密码那就有点太麻烦了,在网上找了一下,可以通过perl生成linux系统用户保存 ...

  2. linux基于此语言的密码,一次有趣的Linux下.Net Core与C语言的合作开发体验:生成Linux标准的用户密码串...

    最近在项目进程中遇上了Linux用户验证的问题,想着怎么样通过Linux本地用户进行安全校验,于是去查了些资料. Linux的密码存储 查阅资料后发现早期的Linux存储在/etc/password文 ...

  3. 用户密码加密存储十问十答,一文说透密码安全存储

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者 | 程序员赵鑫 来源 | cnblogs.com/xinzh ...

  4. PHP 加密用户密码 How to store passwords safely with PHP and MySQL

    Do not store password as plain text Do not try to invent your own password security Do not 'encrypt' ...

  5. linux密码加密方式 2y,手动生成Linux密码(/etc/shadow)

    shadow文件的格式就不说了.就说说它的第二列--密码列. 通常,passwd直接为用户指定密码就ok了.但在某些情况下,要为待创建的用户事先指定密码,还要求是加密后的密码,例如kickstart文 ...

  6. 如何正确对用户密码进行加密?转自https://blog.csdn.net/zhouyan8603/article/details/80473083...

    本文介绍了对密码哈希加密的基础知识,以及什么是正确的加密方式.还介绍了常见的密码破解方法,给出了如何避免密码被破解的思路.相信读者阅读本文后,就会对密码的加密有一个正确的认识,并对密码正确进行加密措施 ...

  7. 如何正确对用户密码进行加密?

    本文介绍了对密码哈希加密的基础知识,以及什么是正确的加密方式.还介绍了常见的密码破解方法,给出了如何避免密码被破解的思路.相信读者阅读本文后,就会对密码的加密有一个正确的认识,并对密码正确进行加密措施 ...

  8. linux 用户密码加密

    生成加密密码 #!/usr/bin/python import crypt,random,string; print(crypt.crypt("123456", '$6$' + ' ...

  9. 移动App该如何保存用户密码

    这个实际上和桌面程序是一样的. 先看下一些软件是如何保存用户密码的: 我们先来看下QQ是怎么保存密码的: 参考:http://bbs.pediy.com/archive/index.php?t-159 ...

最新文章

  1. fortran语言和python_如何在Fortran中调用Python
  2. 总体经济拉动新引擎-农业大健康·张咏:疫情后谋定乡村振兴
  3. mysql列目录_mysql列直接存储图片路径
  4. java mvc 实际分层_SpringMVC体系分层模式原理图解
  5. java(i++和++i的理解)
  6. 由浅到深理解ROS(6)-坐标转换
  7. methods vue过滤器 和_数据动态过滤技巧在 Vue 项目中的实践
  8. 三星Galaxy Fold 2渲染图曝光:怎么折是个问题
  9. UGUI- 单列列表(VerticalLayoutGroup)
  10. 微信第三方平台相关的转发
  11. 禁用oracle的默认账户,Oracle EBS默认的账户
  12. Android之改变控件的背景及形态
  13. aspose.cell for java 去水印_【Java编程基本功】(十)输出杨辉三角,输出*号,数组移动...
  14. GitHub使用(四) - 关于分支Branch
  15. videojs如何获取请求消息_WEB之基于HTTP协议的几种实时数据获取技术
  16. 如何从尚硅谷下载免费的前端开发视频资源
  17. 把书本上的字快速弄到电脑上
  18. maya藤蔓插件_Maya特效制作之植物生长动画制作教程(二)之多条藤蔓动画制作...
  19. 招聘网站分析-前程无忧网站的爬虫设计与实现
  20. 树美滑块验证——滑块识别、获取和提交参数一条龙分析和调用

热门文章

  1. OpenCV-python学习笔记(二)——image processing图像基本处理
  2. Python——腾讯在线编程题(2018)
  3. Linux下数据库mariaDB的管理
  4. Selenium UI自动化测试(二)IDE—使用
  5. mac硬盘挂载不显示(exfat格式)
  6. SAP License:MM模块审批策略问题
  7. MySQL高级知识(四)——Explain
  8. Java面试常问基础知识(持续更新)
  9. run (牛客多校第二场)计数DP
  10. swiper动态加载数据滑动失效,ajax执行后swiper.js的效果消失问题