使用crypt生成用户密码-Tested on RedHat & SuSE Platform
2011-04-05 10:05
519 查看
近期做EasyCluster,需要创建用户,要求在Linux上能创建一个用户帐号,很自然想到了后台程序调用useradd命令行来完成,但众所周 知,密码是个麻烦事。查看了 useradd的手册,有个-p password 选项可以在创建的时候就指定密码,但要求这里的密码是已经加过密的,这就要求用crypt函数进行加密,然后再放入命令行。故测试了一下,写了一段测试代 码,用来生成密码:
Code: Select all
这 里就能生成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
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 即可
相关文章推荐
- Oracle用户密码使用特殊符号,例如&(AND)、$(Dollar)、#(Pound)、*(Star)等
- 【转】Oracle用户密码使用特殊符号,例如&(AND)、$(Dollar)、#(Pound)、*(Star)等
- Linux下利用glibc2库和crypt()函数生成用户密码
- AT&T禁止用户使用“污秽”密码遭调侃
- 使用ADMT3.2迁移2008AD域(三)----用户的迁移(生成复杂密码)
- 使用axis2调用sap生成的webservice(带用户密码认证)
- RedHat系统下的网络配置,主机名的修改,进入单用户模式修改root密码和使用SSH远程连接工具
- 使用Druid生成加密密码,实现mysql数据库连接用户密码加密解密
- FORM中使用onSubmit="return false"防止表单自动提交,以及submit和button提交表单的区别
- c#使用Api函数重设用户密码
- 初次使用phpMyAdmin & MySql修改root密码
- apache密码生成工具htpasswd使用详解
- 使用mkpasswd/$RANDOM生成随机密码
- Oracle 使用scott用户 set autotrace on报错 SP2-0618,SP2-0611
- 使用expect批量修改用户密码
- 关于Windows 2008 IIS无法使用虚拟目录密码作为用户 administrator 在本地登录到...解决方案
- 使用gvim && txt2tags生成google code wiki 格式文件
- FORM中使用onSubmit="return false"防止表单自动提交,以及submit和button提交表单的区别
- 使用keychain保存用户密码,token等
- EasyDemo*Get()&&Set()使用Demo(on Github)