基本知识
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
<code>static</code> <code>const</code> <code>struct</code> <code>crypt_method methods[] = {</code>
<code> </code><code>/* method </code>
<code>prefix minlen, maxlen rounds description */</code>
<code> </code><code>{ </code><code>"des"</code><code>, </code><code>""</code><code>, </code>
<code>2, 2, 0,</code>
<code> </code><code>n_(</code><code>"standard 56 bit des-based crypt(3)"</code><code>) },</code>
<code> </code><code>{ </code><code>"md5"</code><code>, </code><code>"$1$"</code><code>, 8, 8, 0, </code><code>"md5"</code> <code>},</code>
<code>#if defined openbsd </code>
<code>|| defined freebsd || (defined __svr4 && defined __sun)</code>
<code> </code><code>{ </code>
<code>"bf"</code><code>, </code><code>"$2a$"</code><code>, 22, 22, 1, </code><code>"blowfish"</code> <code>},</code>
<code>#endif</code>
<code>#if </code>
<code>defined have_linux_crypt_gensalt</code>
<code> </code><code>{ </code><code>"bf"</code><code>, </code><code>"$2a$"</code><code>, 22, </code>
<code>22, 1, </code><code>"blowfish, system-specific on 8-bit chars"</code> <code>},</code>
<code> </code><code>/* algorithm 2y </code>
<code>fixes cve-2011-2483 */</code>
<code> </code><code>{ </code><code>"bfy"</code><code>, </code><code>"$2y$"</code><code>, 22, 22, 1, </code>
<code>"blowfish, correct handling of 8-bit chars"</code> <code>},</code>
<code>#if defined </code>
<code>freebsd</code>
<code> </code><code>{ </code><code>"nt"</code><code>, </code><code>"$3$"</code><code>, 0, 0, 0, </code><code>"nt-hash"</code>
<code>},</code>
<code>#if defined have_sha_crypt</code>
<code> </code><code>/* http://people.redhat.com/drepper/sha-crypt.txt */</code>
<code> </code><code>{ </code><code>"sha-256"</code><code>, </code><code>"$5$"</code><code>, 8, 16, 1, </code><code>"sha-256"</code> <code>},</code>
<code>"sha-512"</code><code>, </code><code>"$6$"</code><code>, 8, 16, 1, </code><code>"sha-512"</code> <code>},</code>
<code> </code><code>/* http://www.crypticide.com/dropsafe/article/1389 */</code>
<code> </code><code>/*</code>
<code> </code><code>* actually the maximum salt length is arbitrary, but </code>
<code>solaris by default</code>
<code> </code><code>* always uses 8 characters:</code>
<code> </code><code>* http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/ \</code>
<code> </code><code>* </code>
<code>usr/src/lib/crypt_modules/sunmd5/sunmd5.c#crypt_gensalt_impl</code>
<code> </code><code>*/</code>
<code>defined __svr4 && defined __sun</code>
<code> </code><code>{ </code><code>"sunmd5"</code><code>, </code><code>"$md5$"</code><code>, </code>
<code>8, 8, 1, </code><code>"sunmd5"</code> <code>},</code>
<code> </code><code>{ null, null, </code>
<code>0, 0, 0, null }</code>
<code>};</code>
(5)linux系统中的一段实例,可参见/etc/shadow文件
$6$yoursalt$005gz1.zsygebpp/u27h5ijan9crpacufvjrnmb5cfmvfhilunjciv3w3fri1tf4c/thd8mhvpk4i3eviuc8y1
其中,上述字符串中有3个$,$6$代表使用sha-512加密算法, $yoursalt$表示salt的值。
实现
(1)c语言实现:
<code>vim encryptionwithcrypt.c</code>
<code>#define _xopen_source</code>
<code>#include <unistd.h></code>
<code>#include <stdio.h></code>
<code>int</code> <code>main(</code><code>void</code><code>)</code>
<code>{</code>
<code> </code><code>char</code> <code>*encryption;</code>
<code> </code><code>char</code> <code>key[] = </code><code>"yourkey"</code><code>;</code>
<code> </code><code>encryption= crypt(key, </code><code>"$6$yoursalt$"</code><code>);</code>
<code> </code><code>printf</code><code>(</code><code>"encryption is: %s\n"</code><code>, encryption);</code>
<code> </code><code>return</code> <code>0;</code>
<code>}</code>
<code>gcc -lcrypt encryptionwithcrypt.c -o encryptionwithcrypt </code>
<code>.</code><code>/encryptionwithcrypt</code>
(2)其他工具实现:
如果不想借助crypt()函数生成密码,ubuntu用户可以用whois包中提供的mkpasswd,命令得到密码,当然借助其他的工具也有其他办法。
<code># ubuntu only, available on ubuntu</code>
<code>which</code> <code>mkpassed || apt-get </code><code>install</code> <code>-y whois</code>
<code>mkpasswd --salt=</code><code>"yoursalt"</code> <code>--method=sha-512</code>
参考
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--