MD5和Base64混合算法

  MD5与Base64的混合加密算法
  MD5加密算法的单向加密不可逆转的特性,使其在基于B/S架构的用户身份认证系统中得到了比较广泛的应用。目前,几乎绝大部分运行在Intemet上的B/S架构的用户身份认证系统都采用了将用户的密码做MD5加密后存入后台数据库的方法,以防止后台数据库被攻破导致用户密码信息泄露。随着计算机硬件设备的飞速发展,计算机的处理速度和存储容量都大大提高,一种被称为“跑字典”的方法利用了当前先进的计算机硬件,可以将MD5算法破解。这种“跑字典”的方法种采用排列组合方法生成明文的密码字典,先用MD5程序计算出这些字典项的MD5值,然后再用目标的MD5值在这个字典中检索出对应的明文密码,MD5加密算法受到了严峻的挑战。本文介绍了一种基于MD5和Base64的混合加密算法,将MD5加密后的密码串作拆分和连接处理后再采用Base64加密,其破解难度相对于单独的MD5加密方式高,可以更好的保护用户的密码安全.
1 MD5
  消息摘要算法第五版(Message Digest Algorithm,MD5),90年代初由MIT的计算机科学实验室和RSA Data SecurityInc发明。Message—Digest指字节串(Message)的Hash变换,即把一个任意长度的字节串变换成一定长的大整数。MD5将任意长度的“字节串”转换成一个128位2进制数,即32位16进制数。MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被“篡改”。MD5算法的使用不需要支付任何版权费用的,所以被大量公司和个人广泛使用。
  MD5是一个安全的散列算法,输入两个不同的明文不会得到相同的输出值,根据输出密文值,不能得到原始的明文,即其过程不可逆。要解密MD5没有现成的算法,但并不代表MD5算法是绝对安全的,例如使用穷举法,把可能出现的明文,用MD5算法散列之后,把原始的数据和得到的散列值形成一个一对一的映射表,然后比对表中和破解密码的MD5算法散列值,将匹配的散列值对应的明文从映射表中找出,可以破解密码经MD5加密后所对应的原始明文,这种方法也被称为“跑字典”。目前在Intemet上已有网站采用这种方法在后台数据库中生成和存储了大量散列值和明文的数据,提供给用户进行密码查询解码,一旦有采用MD5加密存储用户密码的数据库被攻破,则要得到用户的密码就变得比较容易。因此单独采用MD5加密方式存储用户密码安全性并不是很高,要保证信息系统的用户密码安全,则需要对MD5进行改造。本文研究的内容正是将MD5加密后的密文进行再次加密改造,提高用户的密码安全性。
  2 Base64
  Base64是一种使用64基的位置计数法。它使用2的最大次方来代表仅可打印的ASCII字符,主要应用于电子邮件的传输编码,也可用于加密口令。在Base64中的变量使用字符A—Z、a—z和0—9共62个字符,用来作为Base64编码表中的64个码,最后两个用来作为数字的符号在不同的系统中而不同。
  Base64编码转换的时候,将三个字节的数据,先后放入一个24位的缓冲区中,先来的字节占高位。如果数据不足3
个字节,将缓冲区中剩下的位用0补足。然后,每次取出6位,按照其值选择ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/中的字符(见表1)后的输出。不断进行,直到全部输入数据转换完成。如果最后剩下两个输入数据,在编码结果后加1个“=”;如果最后剩下一个输入数据,编码结果后加2个“=”;如果没有剩下任何数据,则什么都不加。
表1 Base64 编码表

编    码   编  码   编    码  
编   码
0 A   15 P   30 e   45 t
1 B   16 Q   31 f   46 u
2 C   17 R   32 g   47 v
3 D   18 S   33 h   48 w
4 E   19 T   34 i   49 x
5 F   20 U   35 j   50 y
6 G   21 V   36 k   51 z
7 H   22 W   37 l   52 0
8 I   23 X   38 m   53 1
9 J   24 Y   39 n   54 2
10 K   25 Z   40 o   55 3
11 L   26 a   41 p   56 4
12 M   27 b   42 q   57 5
13 N   28 c   43 r   58 6
14 O   29 d   44 s   59 7


根据以上Base64算法的描述,本文以加密字符串“Man”为例,对其进行Base64加密。“Man”中的字符“M”、⋯a’、“n”分别对应ASCII编码中的二进制编码“01001101”、“01100001”、“01101110”,将这3个8位二进制字符串连接成一个24位的二进制数组再进行拆分,每次取6位二进制数,并将取出的6位二进制数补全成8位二进制数,得到4个8位二进制数,“00010011”、“00010110”、“0000010 1”、“00101110”,这4个8位二进制数对应的整数分别为“19”,“22”,“5”,“46”,查Base64编码表,对应“T”、“w”、⋯F’、“U”这4个字符(见表2),因此“Man”的Base64编码为“咧Fu”。上面这个示例一共3个字符,转换成二进制以后一共24位二进制数,位数能被6整除,因此恰好能分成4个6位2进制数,如果明文不是3的整数倍的时候,其二进制编码串的位数不能被6整除,这个时候在密文的末尾要用“=”来进行填
充。

                              表2 Man的Base64 编码

项目    
文本 M a n
ASCII编码 77 97 110
二进制位 01001101 01100001 01101110
索引 19 22              5 46
Base64编码 T W              F u



3 混合加密算法
  前文提到,单一的MI)5加密算法可以查询通过穷举法生成的数据库密码字典的方法进行解码,因此需要对MD5加密算法作一定的改造,才能保障用户的口令安全。本文所研究的混合加密算法正是基于MD5造的一种加密算法,但研究的主要内容不是如何将一串字符通过MD5算法加密,也不是先将明文进行MD5加密然后再对其进行简单的Base64转换,而是将明文通过MD5加密后得到的密文分组成16个2位16进制的数组,通过Base64算法,将密文再做一次加密。这里采用了一种“变异”的Base64算法处理经过MD5加密后
的字符串,之所以称为“变异的Base(:~加密算法”,是因为本文将l6个数组里面存放的处理方式和传统的Base04加密的处理方式略有不同。第2章中介绍的Based4算法是将待处理的字符先进行ASCII编码,然后再进行处理。这里并不是将待处理字符做ASCII编码,而是将待处理的16进制数直接转换成二进制数。转换的步骤如下:第一步,将用户的明文密码做MD5加密,得到32位l6进制密文;第二步,将32位密文拆分位16个2位16进制数组,接下来把所有数组中的16进制数转换成8位2进制数,然后将16个8位2进制数组连接起来形成一个128位二进制数;第三步,从第二步生成的128位2进制数每次截取6位并补全为8位2进制数,按照8位2进制数所代表的1O进制索引查找Base64编码表,得到对应的密文。
  例如,明文字符串为“test”,对该字符串进行MD5加密以后, 得 到 32 位 的 16 进 制 密 文“098f6bed4621d373eade4e832627b4f6”。本文首先定义一个包含16个元素的字符数组Array[16],MD5加密后得到的字符串存人数组中,得到Array[0]=“09”,Array[1]=“8f’,⋯ ,Array[15]=“f6”。以Array[15]为例,如果采用传统的Base64编码,则先对“f'和“6”进行ASCII转换,查AS CII编码表,“f”和⋯6’分别对应ASCII编码的二进制编码“O1100110”和“00110110”,连接这两个二进制码,采用Base64编码算法进行加密,Array[15]对应的密文为“ZT=”。和传统的Base64加密算法先将明文转换成ASCII码不同,这里采用了将明文直接转换成对应的二进制数,同样以Array[15]为例,十六进制数“f’和⋯6分别对应二进制数“1111”和“0l1O”,连
接这两个二进制数得到“11110110”,与处理Array[15]类似,分别处理数组Array[0],⋯ ,Array[15],然后将所有数组转换成的二进制数连接成一个128位的2进制数,即最初的明文密码“test” 处理得到128 位的2 进制数“0o0o100l1O0ol1 1 101 10101 l1 1ool1O1OlOool1OoolOooOl1 101001 101 l10011 110010101 101 l1 10o10o11 10l0oo0ol10ol0ol1000100111101101O011110110”。根据Base64的编码规则,从128位二进制数中每次取出6位,高位补0为8位2进制数,得到对应的Base64编码索引,根据编码索引查询Base64编码表得到对应编码,如本文首先取出128位2进制数中的前6位“000010”,高位补0后得到“00000010”,对应的十进制数为2,这个十进制数2即为Base64表索引;然后根据这个索引查Base64编码表得到对应的编码为“C”,依此类推,直到取完128位二进制数,最后剩下了2位未进行编在编码末尾加两个“=”补全,根据以上加密处理后,得到加密后的密码为“CY9rzUYh03PK3k6D Jie09C==”。
4 混合加密算法实现
  由于MD5加密算法在Web编程技术中应用非常广泛,几乎所有的Web脚本语言里面都有MI)5加密算法的实现接口,例如在PHP中,可以直接调用MD5函数对明文进行加密,格式为MD5(“string”)。根据图1中的描述,混合加密算法需经过3个步骤,即进行MD5加密、拆分MD5加密后的字符串并转换为2进制数、对2进制数组进行连接和Base64加密操作,因此在实现混合加密算法时,需要设计相应功能的函数,这里一共定义了如下4个函数:
1)function pwd2MDSPwd($user_pwd);
2)function pwd_split_fune($pwd_md5);
3)function hex2bin_8bit($hex_num);
4)function mdS_base64_hybrid($pwd)
其中第一个函数的功能是将参数$user_pwd获取到的值转换为MD5加密后的密文,即用户提交的明文转换成MD5加密后的密文,将字符串“test”转换成32位16进制串“098f6bed4621d373cade4e832627b4f6”。
  第二个函数的功能是将MD5加密后的32位l6进制串拆分成16个2位16进制数组,PHP中函数str_split可以把函数按照固定的长度进行分割,其格式为str—sput($string,$1ength),其中参数string表示待分割的字符串,length表示分割的字符串长度。函数pwd—md5一spHt—func($pwd—md5)接收到MD5加密后的字符后,将字符串传给str_split按照每次取两位(即length参数设置为2)拆分字符串,然后将16个字符串存人数组中,最后循环调用第三个函数,将所有数组中的l6进制数转换成为2进制数,并连接成一个128位的2进制数。
第三个函数的功能是将16进制数转换成8位2进制数,由于MD5加密后得到的是32位16进制数,因此每个数组的取值范围为十六进制的00~f。PHP中提供直接将M进制转换为N进制的函数base—conve~,其格式为base—conve~($number,$frombase,$tobase),参数number表示要转换的数字,frombase表示转换前的进制,tobase表示转换后的进制,例如本文把拆分的16个16进制数组中的第一个元素转换成2进制的表示方式为base_conve~(Array[0],16,2)
  第四个函数的功能是将第二个函数得到的128位2进制数每次取出6位,每取一次在前面加2个0补成8位2进制数,然后取出的8位2进制数转换为10进制数并查询Base64表得到对应的密文。末尾不足6位,在密文末尾添加两个“= ”补全。
  本文介绍了一种基于MD5和Base64的混合加密算法,详细介绍了该算法的具体实施步骤,采用PHP脚本语言实现了该算法,该算法可应用于B/S结构的身份认证系统中,即使该系统的数据库信息泄漏,用户的密码也不会被“跑字典”的方法查询密码字典库破解,更加有效地保证了用户的密码安全。
                                                         打字和打表很累的。。

posted @ 2013-06-16 09:18  何胖子  阅读(2919)  评论(1编辑  收藏  举报