为防止网络应用系统中字符型密码被非法用户通过“跑字典”破译,并能为网络用户找回丢失的密码,同时也为远程访问数据库做数据同步提供便利,我们提出了一种对字符型密码采用线性随机加密与解密的算法,并用JavaScript语言实现了加密与解密过程。
一、字符型密码加密现状分析
密码加密算法与解密算法有很多,例如著名的MD5加密算法和RSA加密算法等,其中分为可逆与不可逆算法,比如MD5加密算法是不可逆的,经MD5加密后的密文无法还原出原始密码,应用系统只能将用户输入的原始密码按MD5加密算法运算后所得到的密文与实现经同样算法所生成的密文进行对比方能验证用户的合法性,此方法最大的优点是任何人都不可能篡改用户密码,具备很高的安全性,目前的WEB系统中,对用户密码的加密,更多的是应用MD5进行加密。
采用MD5加密,可以在一定程度上保证用户密码的安全性,但也有不足之处,主要表现在以下3个方面:
(1) MD5是单向加密算法,加密后的信息不能解密,用户丢失密码后只能重盈密码,而没有任何方法找回密码。
(2)不同的密码经MD5加密后有可能形成同一密文,虽然概率极低,但还是可能出错,也就是说用户不用原始密码而用另一密码也可能成功登录。
(3)也是最关键之处,经MD5加密后的密文由于无法还原,所以在需要还原原始密码的应用中就不能使用,比如某些网站为了方便用户下次登陆而设有保存密码的功能,一般来说使用浏览器的cookie来保存用户ID和登录密码,以便下次用户登录时系统自动为用户填写用户ID和登录密码,但利用cookie来保存用户登录密码是不安全的,稍懂点网络编程的人就可以进入用户的计算机找出相应的cookie来窃取用户的登录密码。所以利用cookie保存用户登录密码时需要经过一定的加密处理,并且经加密过的密文可以由一定的算法还原出原始密码。又比如某些分布式网络应用系统需要同步数据库的内容,而访问远程数据库就必须有远程数据库的密码,而这个密码必须保存在本地而且需要进行加密处理,并且加密后的密文还应该有一定的算法来还原出原始密码。因此MD5加密算法在一定的场合下不能满足需求。基于以上的需求,设计出一套新的加密算法与解密算法有着重大的意义。
二、字符型密码随机加密算法与解密算法
1、字符型密码随机加密算法设计思想
基于字符型密码随机加密算法与解密算法的核心功能实质上就是字符串的加密与解密。设计要求有以下三点:
①算法相对简单,加密与解密运算速度快,消耗机器资源少。
②在得不到原始算法的基础上进行解密难度很大,无论是暴力破解还是技术破解都无法在短时间内完成解密,只能根据加密算法的逆运算才能正确解密。
③不担心密文泄露,破解者即使拿到多套正确的原始密码与加密后的密文也无法得出加密参数。
2、加密算法与密钥设计
按以上要求进行算法设计,经本人研究发现,绝大多数用户密码都是由计算机键盘上的可见字符组成,而计算机键盘上的可见字符ASC码范围为33到126,本文以最长8位密码为例进行算法设计和实现,对于任何一个可见字符,其ASC码的范围为33到126,其中包括所有的英文字母,数字,标点符号等。反过来说,对于任何一个在33至126内的数字都对应着一个字符。因此设计出一个线性加密算法,y=ax+b。其中,y为加密后的数值,x为原始散值,对应着密码中的某一字符,a和b是两个随机数。
线性加密参数设计:由线性加密公式y= ax+b和密文组成原则可知,y的取值范围为AA到ZZ,换算成十进制值为O到675,x为原始密码的某一位经ASC转换而来。所以x的取值范围为33到126,因此得到如下关系:其中x,y,a,b皆为正整数
y=ax+b
yo
x32
另外为了缩小参数范围,降低计算量,可以增加设定
a>0
b>o
由以上关系解得O<a<6
以下用穷举法分别求出对应于不同a值的b的取值范围
当a=1时,解得O<b<549
当a=2时,解得O<b<423
当a=3时,解得o<b<297
当a=4时,解得O<b<171
当a=5时,解得o<b<45
程序设计中a由系统随机生成,范围为O<a<6,上限是5,下限是1。b的范围用一个一维数组限制其上限,[549,423,297,171, 45]分别对应不同a值时的取值范围,下限是1。
3、密文结构设计
密文结构设计:密文由32位26进制数组成,用大写字母A到Z表示每一位,其中A到Z分别表示十进制的0到25,原始密码字符串最大长度为8位,每一位经线性加密后用2个大写字母表示其加密密文,因此完全表示最长密码只需16位,根据上面分析所得的ab参数范围,设计用1位表示随机线性加密系数a,1位表示原始密码字符串实际长度(字符个数),2位表示b,总共用20位表示完所有信息,剩下12位作为随机混淆处理位,分别插入前面11个(22位)信息之间,并在密文首尾各加一位随机值,以增加破解难度。此外,为了防止大多数用户密码长度相同(比如大多取8位)时所生成的长度加密位相同,长度位也用采用加密处理,本例用参数a的十进制值加上实际长度值所得结果再经26进制转换而成,这样得到的原始密码长度也是个随机数,即使两个用户密码长度相同但在密文中对应的长度位也会不同。让破解者找不到任何规律。当原始密码长度小于8位时,用随机26进制直补齐8位。解密时根据长度位计算结果舍奔随机补充部分。本例加密算法采用如下密文结构:
密文位散 相应位数的值
0: 随机值
1-2: 加密后的线性加密参数b
3: 随机值
4: 加密后的原始字符串文长度
5: 随机值
6-7: 加密后的原始字符串第1位
8: 随机值
9-10:加密后的原始字符串第2位
11: 随机值
12-13:加密后的原始字符串第3位
14: 随机值
15-16:加密后的原始字符串第4位
17: 随机值
18-19:加密后的原始字符串第5位
20: 随机值
21-22:加密后的原始字符串第6位
23: 随机值
24-25:加密后的原始字符串第7位
26: 随机值
27-28:加密后的原始字符串第8位,原始密码不足8位的用随机值得补齐8位
29: 随机值
30: 加密后的线性加密参数a
31: 随机值
4、加密算法、解密算法流程
图1是本算法的加密流程,图2是本算法的解密流程,下面分别对加密、解密过程进行说明
(1)加密过程
以字符型密码“Dca8? d3@”为例说明加密过程:首先生成随机加密参数a(B的取值范围为1-5)。如本例中a=4,然后进行下面的流程:
(1)根据生成的a值查表(程序中用数组表示)得到参数b的最大值maxb,然后在1-maxb之间生成随机参数b。如本例中b=92。
(2)取明文字符串长度I,然后加参数a,生成长度位L。如本饲中L=4+8=12。
(3)填写密文前7(0—6)位,方法为,第0位随机生成,本例是Z,第1,2位为加密参数b的26进制值,本例为D0-92,第3位为混淆随机值,本例为Q,第4位为原字符串长度加参数a所得结果的26进制值,本例为4+8=12=M。第5位为混淆随机值,本例为0。
(4)分别取明文中的每一个字符(如例1中第一字符D)进行ASC码转换,如D的ASC值为68,然后将此ASC码值经线性加密公式y=ax+b得出加密后的数值,此例中,Y=ax+b=4*68+92=364。
(5)将第4步得到的数值转换成两位26进翩值,如t026 (364)=OA。
(6)添加一位随机大写字母,用于混淆,此例中为H。
(7)循环做(5)一(7),本例得到SUNSMMMEDN-GRSYYLKJNKX。
(8)假如字符原字符串长度小于8,则随机补充到8位,每差一位补齐3个随机值。本例中长度正好位8位,所以不补充。
(9)填写加密参数a的26进制值,本例为a=4=E。
(10)生成随机混淆值,本例为L。
则本例中密文为:ZDOQMOOAHSUNSMMMEDN-GRSYYLKJNKXEL。
因为加密参数a、b是随机的,所以同一明文可以得到不同的密文,如表1所示。
(2)解密过程
以密文“OQMOOAHSUNSMMMmNGRSYYLKJN-KXEI”为例说明解密过程:
(1)读出密文,并检查密文结果,检查内容为密文长度必须为32位,密文必须全由大写字母组成,否则密文有错,不是正常加密所得密文。
(2)取密文第30位(密文第一位为0位)值,本例为E,转换为10进制数为4,得加密参数a为4。
(3)取密文第4位值,本例为M,转换为10进制值为12,减去第二步中得到的a值,得到原始字符串(明文)的长度,本例为12-4=8。
(4)检查第(3)步中得到的长度,假如长度值小于1或大于8则密文有错,报告错误并停止运行。
(5)取密文第1,2位,本例为DO,转换为十进制值为92,得到加密参数b。
(6)从密文的第6位开始循环取3位(循环次数为第3步中得到的长度,本倒为8)。然后取3位中的前两位进行十进制转换,本例循环8次,分别得到OA= 364,SU,SM.ME,NG.SY,LK,NK等。
(7)由加密公式y-ax+b得解密公式为x-(y-b)/a,分别算出第6步得到的值,本例中第一个字符解密结果为x-(y-b) /a- (364-92) /4-68。
(8)经ASC码逆转换得到第(7)步所的数的字符。
(9)连接循环解出的每一位得到解密结果,本例为Dca8? d3@。
同一明文的不同次数加密得到的不同密文,经过解密后可以得到相同的明文,如表2所示。
三、字符型密码如何随机加密与解密
本文用JavaScript语言实现了加密与解密过程,其中设计了以下函数;
十进制散转26进制函数:t026 (x),作用,返回十进制数x的26进制值。
该函数根据传人参数x生成26进制值。用符号A至Z表示26进制的0到25,根据密文组成规则,该函数至少返回两位值,例如t026 (0)=AA。
26以内的十进制数转单个26进制字符函数:toSg26(x)
该函数传入参数x的范围在0-25,函数返回单个26进制字符,主要用于表示密文中单个随机混淆值和参数a和字串长度值等,例如to\Sig26 (3)=D。
26进制转十进制函数:tol0 (s),作用为把26进制字符串转换成十进制数返回,参数s为26进制字符串,例如tol0 (BC)=28。
随机数产生函数:Random(rrun,max),作用为产生参数nun到max内的随机数,包括nun和max。
加密主函数:Encryption (s),作用为对于任何传入参数(小于等于8位)。返回32位26进制字符串。
解密主函数:Decryption (s),对于用加密模块加密后的32位字符串,解密还原出加密以前的原址字符串。
图3为密码"Dca8? d3@"的加密、解密示例。
小知识之MD5加密
MD5的全称是Message-Digest Algorithm 5(信息-摘要算法),在90年代初由MIT Laboratory for Computer Science和RSA Data Security Inc的Ronald L. Rivest开发出来,经MD2、MD3和MD4发展而来。