1.现有技术的缺陷
在用户登录模块,本文将以中国知网(www.cnki.net)为例进行对比分析。登录功能是大多数系统都有的模块,完成功能并不难,但是如何做到安全,这是一个比较难得问题。下图5-1是于2014年5月28号在登录知网时通过浏览器截取的http请求内容。在该图中可以看到,Form Data部分用户名:555555及密码:555555都是未经加密传输的明文字符。而明文传输将引起非常多的安全隐患,任何人都可以读取并捕获明文信息。从而导致用户账号被泄露。
图5-1 中国知网登录http协议截图【WEGOTEAM】
2.本系统的改进
在现有条件下,对用户密码进行保护主要有两种方式,一种是摘要认证,一种是使用安全的https。由于后者需要向第三方购买认证,成本较大,因此本系统将采用摘要认证。在本系统登录中,系统采用了Base64、MD5算法、随机码、时间戳等技术,对用户的登录密码与随机码、时间戳混合并进行两次MD5运算,从而可以有效保护用户密码,并能防止攻击者恶意篡改及对服务器进行重放攻击。
3.登录的具体实现
(1).在浏览器端对用户的输入的密码进行两次MD5运算,对用户名进行Base64运算,对随机码进行一次MD5运算。具体代码如下:
var temppassword=$.md5(parseInt((new Date()).valueOf()/10000)
+$.md5($("#password").val())+$("#randcode").val());
$("#Md5randomImageStr").val($.md5($("#randcode").val()));
$("#Md5password").val(temppassword);
$("#Base64userName")
.val($.base64.encode($("#username").val()));
在该代码中,系统首先获得了当前时间戳,并除以10000并取整,从而可以获得当前时间,单位为10秒。接下来系统对用户输入的密码进行一次MD5运算,最后系统将取整后的时间戳与一次MD5运算后的密码及用户输入的随机码混合并进行二次MD5运算,最终获得了登录密码摘要。在对密码进行处理后,系统还分别对随机码进行了一次MD5运算,对用户名进行了一次Base64运算。最终登录时的http协议如图5-2所示,从该图中可以看到,Form Data中的username,password,randcode都是加密过后的数据。
图5-2 本系统登录http协议截图【WEGOTEAM】
(2).在对浏览器端数据进行加密后,系统要完成正确的用户登录,服务器端必须采用与客户端响应的运算规则。首先服务器必须判断验证码是否正确,代码如下:
String str2 = (String) (session.get("random"));
if(str2==null||!this.getRandcode()
.equals(Tools.encrytMD5(str2.toLowerCase()))){
message= "验证码有误";
return "loginerror";
}
在本段代码中,系统首先从服务器端获取生成随机码图片时保存的验证码,在获得验证码后,将验证码进行一次MD5运算并与用户输入的进行判断。该验证码技术的使用能有效防止非法用户使用机器暴力破解系统。
(3).在对验证码进行判断后,系统需要根据用户名查询用户的详细信息,具体代码如下:
user.setUsername(new String(Base64.decode(user.getUsername())));
String strHQL = "from User u where u.username = ? and u.state>=1";
users = this.userService.findByHQL(strHQL, user.getUsername());
if (users.size() == 0) {
message = "用户名不存在!";
return "loginerror";
}
(4).获得用户详细信息后,系统需要在服务器端采用相同计算用户登录摘要,并将计算得到的摘要与用户的输入进行比对,具体代码如下:
long curTime=System.currentTimeMillis()/10000;
String tempPassword=curTime+users.get(0).getPassword()
+str2.toLowerCase();
curTime=curTime-1;
String tempPassword2=curTime+users.get(0).getPassword()
+str2.toLowerCase();
if(!user.getPassword().equals(Tools.encrytMD5(tempPassword))
&&!user.getPassword().equals(Tools.encrytMD5(tempPassword2))){
message= "登录超时或密码有误";
return "loginerror";
}
在本段代码中,系统首先获得当前时间戳,并除以10000,获得当前的时间,单位为10秒。由于网络传输需要一定时间,因此服务端需要考虑传输对时间戳的影响。如:假如浏览器发送请求时的时间为40000毫秒,除以10000后取整的结果为4,单位为10秒,此时假如服务器接到请求是的时间为59000毫秒,除以10000取整后为5。考虑到网络传输,本系统在服务器端生成了两个密码摘要,一个是以时间戳为5生成的,一个是以时间戳为5-1=4生成的。只要客户端的密码摘要和服务器端两个密码摘要中的一个相等,用户即可登录。故该设计允许用户请求提交的范围为40到59,故该摘要的的最大有效时间为59-40=19秒,最小时间为59-49=10秒。
4.登录设计创新
在用户登录过程中,由于验证码是以图片形式传输的,因此可以有效避免黑客通过程序来获得验证码内容,同时系统采用的短时间戳设计,能缩减密码摘要的有效时间。而这两种方法的融合能有效防止黑客通过程序或手动抓取http协议包从而实现非法登录系统。因此本系统能有效防止首部篡改和重放攻击。在一定程度上能给攻击者造成很大的障碍,从而达到保护系统的目的。