本文共 3122 字,大约阅读时间需要 10 分钟。
基本知识
Linux用户的密码由函数crypt()实现。crypt()是一个密码加密函数(将密码加密,明文变成密文),该函数基于数据加密标准(DES,Data Encryption Standard )算法以及基于DES的其他变种算法,该函数不依赖于计算机硬件实现数据加密。DES算法仅适合于加密字符串,也就是用于生成密码。尽管密码的生成有很多种方法。
(1)关于salt
salt是一种混淆key的一段范围在abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./中的“随机”字符串,具体最小长度和最大长度根据加密方法的不同而不同。更多信息可以参考网上的其他文档。
(2)加密策略
更精准的说,输入到系统中所谓密码,只是一个打开一段加密内容的key而已。按照这种说法,可以这样理解:
unique key+unique salt --> unique encryption,即根据key和salt能得到唯一的加密内容。
但最好的期望是:
unique encryption + unique salt !--> unique key,即根据加密内容和salt不能逆向得到key。
(3)关于glibc2和ctypt的相关知识,可以man glibc和man crypt的Linux Programmer's Manual ( 3, 7 ) 部分,或者自行搜索相关文档
(4)关于加密方法:
CentOS和Ubuntu里面的密码都是使用sha-512加密方法,sha-512与数字6对应。
其他的加密方法可以参考如下一段C语言定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | static const struct crypt_method methods[] = { /* method prefix minlen, maxlen rounds description */ { "des" , "" , 2, 2, 0, N_( "standard 56 bit DES-based crypt(3)" ) }, { "md5" , "$1$" , 8, 8, 0, "MD5" }, #if defined OpenBSD || defined FreeBSD || (defined __SVR4 && defined __sun) { "bf" , "$2a$" , 22, 22, 1, "Blowfish" }, #endif #if defined HAVE_LINUX_CRYPT_GENSALT { "bf" , "$2a$" , 22, 22, 1, "Blowfish, system-specific on 8-bit chars" }, /* algorithm 2y fixes CVE-2011-2483 */ { "bfy" , "$2y$" , 22, 22, 1, "Blowfish, correct handling of 8-bit chars" }, #endif #if defined FreeBSD { "nt" , "$3$" , 0, 0, 0, "NT-Hash" }, #endif #if defined HAVE_SHA_CRYPT /* http://people.redhat.com/drepper/SHA-crypt.txt */ { "sha-256" , "$5$" , 8, 16, 1, "SHA-256" }, { "sha-512" , "$6$" , 8, 16, 1, "SHA-512" }, #endif /* http://www.crypticide.com/dropsafe/article/1389 */ /* * Actually the maximum salt length is arbitrary, but Solaris by default * always uses 8 characters: * http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/ \ * usr/src/lib/crypt_modules/sunmd5/sunmd5.c#crypt_gensalt_impl */ #if defined __SVR4 && defined __sun { "sunmd5" , "$md5$" , 8, 8, 1, "SunMD5" }, #endif { NULL, NULL, 0, 0, 0, NULL } }; |
(5)Linux系统中的一段实例,可参见/etc/shadow文件
$6$yoursalt$005Gz1.zSYgebPp/u27h5ijAn9crpAcuFVJrnMb5CFmVfhIluNJCIv3w3frI1TF4C/THD8MHVpk4i3eVIuc8y1
其中,上述字符串中有3个$,$6$代表使用sha-512加密算法, $yoursalt$表示salt的值。
实现
(1)C语言实现:
1 | vim encryptionwithcrypt.c |
1 2 3 4 5 6 7 8 9 10 11 | #define _XOPEN_SOURCE #include <unistd.h> #include <stdio.h> int main( void ) { char *encryption; char key[] = "yourkey" ; encryption= crypt(key, "$6$yoursalt$" ); printf ( "encryption is: %s\n" , encryption); return 0; } |
1 2 | gcc -lcrypt encryptionwithcrypt.c -o encryptionwithcrypt . /encryptionwithcrypt |
(2)其他工具实现:
如果不想借助crypt()函数生成密码,Ubuntu用户可以用whois包中提供的mkpasswd,命令得到密码,当然借助其他的工具也有其他办法。
1 2 3 | # Ubuntu only, available on Ubuntu which mkpassed || apt-get install -y whois mkpasswd --salt= "yoursalt" --method=sha-512 |
参考
man 3 crypt
man 3 shadow man 5 sahdow mkpasswd的源码,可通过apt-get source whois获得,解压tar.xz文件的方法:xz -d whois_5.1.1.tar.xz && tar xf whois_5.1.1.tar。tag:Linux密码加密方式,Linux密码加密工具,Linux加密算法,Linux crypt(),mkpasswd whois
--end--
本文转自 urey_pp 51CTO博客,原文链接:http://blog.51cto.com/dgd2010/1712244,如需转载请自行联系原作者