linux crypt函数

linux crypt函数


1. crypt定义

#define _XOPEN_SOURCE /* See feature_test_macros(7) */

#include <unistd.h >

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

上面是man 3 crypt看到的crypt函数定义。

从定义中看到要想使用crypt函数那么就得定义_XOPEN_SOURCE宏,有一些人只是把unistd.h包含进来,然后发现编译的时候出现crypt未定义的情况。

2. key、salt

在TLPI一书中提到“crypt()算法会接受一个最长可达8字符的密钥(即key),并施以数据加密算法(DES)的一种变体。salt参数指向一个两个字符的字符串,用来扰动(改变)DES算法。该函数返回一个指针,指向长度13个字符的字符串。”,这个对crypt函数的一个看似简单的描述让我顿时产生了两个疑问:

  1. 难道crypt函数最多只能处理8字符的密钥吗?是不是意味着crypt(“liulaogen123”, “salt”)==crypt(“liulaogen234”, “salt”)?
  2. salt最多只能是两个字符吗?那这个salt得组合那就非常有限,对于防止碰撞就非常弱了。

“实践是检验真理的唯一标准”,那么我们就用代码来验证我的疑问:

/*************************************************************************
    > File Name: auth.c
    > Author: lxg
    > Mail: [email protected]
    > Created Time: 2015年06月28日 星期日 10时27分19秒
 ************************************************************************/

#define _XOPEN_SOURCE
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>

int main(int argc, char *argv[])
{
    if(argc != 3)
    {
        fprintf(stderr, "%s salt key\n", argv[0]);
        return 1;
    }
    char *encrypted = NULL;

    if((encrypted = crypt(argv[2], argv[1])) == NULL)
    {
        fprintf(stderr, "crypt error:%s\n", strerror(errno));
    }

    printf("%s encrypted:%s\n", argv[2], encrypted);

    return 0;
}

[email protected]:~/station/TLPI/chapter_8$ ./auth abc liulaogen123

liulaogen123 encrypted:abJHmGH1Hal.6

[email protected]:~/station/TLPI/chapter_8$ ./auth abc liulaogen234

liulaogen234 encrypted:abJHmGH1Hal.6

[email protected]:~/station/TLPI/chapter_8$ ./auth abc liulaogn234

liulaogn234 encrypted:abjcY/j5FUQVg

从上面的输出来看确实验证了我们的第一个疑问,crypt接受一个最长可达8字符的密钥key,大于8个字符的部分会被丢弃。

[email protected]:~/station/TLPI/chapter_8$ ./auth abc liulaogn234

liulaogn234 encrypted:abjcY/j5FUQVg

[email protected]:~/station/TLPI/chapter_8$ ./auth abd liulaogn234

liulaogn234 encrypted:abjcY/j5FUQVg

[email protected]:~/station/TLPI/chapter_8$ ./auth acd liulaogn234

liulaogn234 encrypted:acJlJNjY0hjOQ

上面的这个示例解答了第二个疑问,crypt的salt指向一个两个字符的字符串,大于2个字符的部分会被丢弃。

上面的两个示例的输出来看无论输入是什么输出的的都是长度为13个字符的字符串。

3. crypt的算法

crypt默认使用的密钥长度为56bit的变体DES算法,我们知道56bit的DES加密在现在日益加强的软、硬件条件下很容易就被破解了,在crypt的man手册中也给出了warning:

Warning: The key space consists of 2**56 equal 7.2e16 possible values. Exhaustive searches of this key space are possible using massively parallel computers. Software, such as crack(1), is available which will search the portion of this key space that is generally used by humans for passwords. Hence, password selection should, at minimum, avoid common words and names. The use of a passwd(1) program that checks for crackable passwords during the selection process is recommended.

那么crypt还有其它的算法吗?因为从上面的key、salt章节和默认使用的DES算法来看这个函数基本是不能用的,我们伟大的linux应该是不会允许这样弱的东西存在的。那么我们接着man手册往下看,在NOTES中我们发现了crypt更强大的部分,在glibc2版本的crypt函数中支持额外的加密算法

crypt支持的额外加密算法有MD5、Blowfish(某些特定的Linux系统支持)、SHA-256(glibc2.7开始)、SHA-512(glibc2.7开始),怎么来区分这些额外的加密算法呢?那就是通过salt来进行区分,如果salt以“$id$salt$encrypted” 这样的格式那么就会根据id的不同值选择不同的加密算法来代替默认的DES算法,id的格式如下:

          ID  | Method
          ─────────────────────────────────────────────
          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)

$5$salt$encrypted 的salt代表crypt函数使用SHA- 256加密算法

$6$salt$encrypted 的salt代表crypt函数使用SHA-512加密算法

$salt$ 中的salt最多支持长度为16字符的字符串,相比默认的DES算法支持最长为2字符有了很大的改进,最后crypt的返回值根据加密算法的不同也有不同长度的字符串返回。

   MD5     | 22 characters
   SHA-256 | 43 characters
   SHA-512 | 86 characters

4. linux密码验证

我们可以查看一下linux中(ubuntu)中密码验证使用的加密算法,怎么来确定呢?其实很简单,查看/etc/shadown文件中密码加密部分就能知道:

$6$at9hFDRi$bTr371ETSBzrRi3e3d229Bedn8g97shPktUcdGk2GlB2Nj2KWTxPmY0wBx A0Xn2395lAgX6ltLnbKvvzgXjhc.

上面是我截取的我电脑中shadow文件root用户的密码部分,从这里可以看出ubuntu使用的是AES-512加密算法。

关于密码推荐大家看这篇文章:passwords

时间: 2024-11-04 14:45:19

linux crypt函数的相关文章

crypt()函数

数据加密 数据加密利用密码技术对信息进行加密,实现信息的隐蔽,从而起到保护信息安全的作用.它通过加密算法和加密秘钥将原来是明文的文件或数据进行处理,使其成文不可读的一段代码,也就是所谓的“密文”,来达到保护数据的安全性. Crypt()函数 crypt()函数返回使用DES.Blowfish或MD5算法加密的字符串.在不同的操作系统上,crypt()函数的行为不同,某些操作系统支持一种以上的算法类型.在安装时,PHP回忆检查什么算法可用以及使用什么算法. crypt()函数的语法: string

linux内核函数库文件的寻找

linux内核函数的so库文件怎么找呢? 首先还是要产生一个进程的coredump文件的 linux有一个lib-gdb.so库,这个进程的coredump文件中所有load段的最后一个load段中,通过读取二进制文件将最后一个load段读取出来保存lib-gdb.so库文件,这个库文件就是内核函数的库文件. coredump文件头->多个程序头(每一个程序头都会对应一个load段)->通过程序头读取load段

Linux mmap函数简介

一.简介 Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上), 通过对这段内存的读取和修改, 实现对文件的读取和修改, 先来看一下mmap的函数声明: 头文件: <unistd.h> <sys/mman.h> 原型: void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offsize); 返回值: 成功则返回映射区起始地址, 失败则返回MAP_FAI

动态替换Linux核心函数的原理和实现

转载:https://www.ibm.com/developerworks/cn/linux/l-knldebug/ 动态替换Linux核心函数的原理和实现 在调试Linux核心模块时,有时需要能够实时获取内部某个路径上的某些函数的执行状态,例如查看传入的变量是否是期望的值,以便判断整个执行流程是否依然正常.由于系统运行时的动态性,使得在执行之前无法预先知道在执行路径的什么地方可能出现问题,因此只能在整个路径上增加许多不必要的信息查询点,造成有用的状态信息被淹没,而且这种增加信息输出的方式(一般

linux进程调度函数浅析(基于3.16-rc4)

众所周知,进程调度使用schedule()函数来完成,下面我们从分析该函数开始,代码如下(kernel/sched/core.c): 1 asmlinkage __visible void __sched schedule(void) 2 { 3 struct task_struct *tsk = current; 4 5 sched_submit_work(tsk); 6 __schedule(); 7 } 8 EXPORT_SYMBOL(schedule); 第3行获取当前进程描述符指针,存

linux fcntl函数

linux fcntl函数 #include <unistd.h>#include <fcntl.h>int fcntl(int fd, int cmd);int fcntl(int fd, int cmd, long arg);int fcntl(int fd, int cmd, struct flock *lock); [描述]fcntl()针对(文件)描述符提供控制.参数fd是被参数cmd操作(如下面的描述)的描述符.针对cmd的值,fcntl能够接受第三个参数int arg

linux 时间函数

linux 时间函数: time/time_t  秒 ftime/ struct timeb 毫秒 gettimeofday/struct timeval us clock_gettime/ struct timespec ns gmtime/localtime/timegm/mktime/strftime/struct tm 其中 time 精度低, ftime 已废弃, clock_gettime 系统调用,精度高 gettimeofday  vsyscall ,系统态, 开销低 定时函数,

linux 系统函数之 (dirname, basename)【转】

转自:http://blog.csdn.net/peter_cloud/article/details/9308333 版权声明:本文为博主原创文章,未经博主允许不得转载. 除非你的原件考虑跨平台. 在Linux编程多使用一些系统函数真的很方便,哎没办法越来越懒~~~~~~ 今天记录一下dirname 和basename这两个简单的处理文件路径的linux系统函数. 头文件: #include <libgen.h> 函数定义: char *dirname(char *path); char *

linux文件函数-open

linux文件函数-open 一 打开文件 函数名:open 函数原形: int open(const char *pathname, int flags) int open(const char *pathname, int flags, mode_t mode) 函数功能:打开或者创建一个文件或者设备 所属头文件: #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> 返回值:成功返回文件描述符,失