基于MD5的网页登陆安全认证
基于MD5的网页登陆安全认证
版本:V1.0
上一版本:V1.0
修订时间:2013.05.29
文件编号:
目录
1. 概述 (1)
2. 基于MD5的网页登陆安全认证详细设计 (3)
2.1. 网页登陆安全认证系统结构 (3)
2.2. 网页登陆安全认证相关文件 (3)
2.3. 脚本详细设计 (4)
2.4. 日志文件(log文件)格式 (5)
3. 登录页最小化范例 (5)
1.概述
由于智能家居系统可以通过Web进行访问与控制,就需要有安全的登录认证机制,保证用户信息的安全。
本功能使用MD5验证机制,使用户在登录过程中不直接传输用户名、密码,登陆时只向WEB 服务器提交由用户名、密码、服务器发来的随机字符串作为原文进行MD5加密后的密文,服务器端做同样的计算,并比较密文,如果两者密文相同,则表示用户名、密码正确。
2.关于网页安全登录认证的分析
MD5还广泛用于操作系统的登陆认证上,如Unix、各类BSD系统登录密码、数字签名等诸多方。如在UNIX系统中用户的密码是以MD5(或其它类似的算法)经Hash运算后存储在文件系统中。当用户登录的时候,系统把用户输入的密码进行MD5 Hash运算,然后再去和保存在文件系统中的MD5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这可以避免用户的密码被具有系统管理员权限的用户知道。MD5将任意长度的“字节串”映射为一个128bit的大整数,并且是通过该128bit反推原始字符串是困难的,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。所以,要遇到了md5密码的问题,比较好的办法是:你可以用这个系统中的md5()函数重新设一个密码,如admin,把生成的一串密码的Hash值覆盖原来的Hash值就行了。正是因为这个原因,现在被黑客使用最多的一种破译密码的方法就是一种被称为"跑字典"的方法。有两种方法得到字典,一种是日常搜集的用做密码的字符串表,另一种是用排列组合方法生成的,先用MD5程序计算出这些字典项的MD5值,然后再用目标的MD5值在这个字典中检索。我们假设密码的最大长度为8位字节(8 Bytes),同时密码只能是字母和数字,共26+26+10=62个字符,排列组合出的字典的项数则是P(62,1)+P(62,2)….+P(62,8),那也已经是一个很天文的数字了,存储这个字典就需要TB 级的磁盘阵列,而且这种方法还有一个前提,就是能获得目标账户的密码MD5值的情况下才可以。
这种加密技术被广泛的应用于UNIX系统中,这也是为什么UNIX系统比一般操作系统更为坚固一个重要原因。
对于 Web 应用程序,安全登录是很重要的。但是目前大多数 Web 系统在发送登录密码时是发送的明文,这样很容易被入侵者监听到密码。当然,通过 SSL 来实现安全连接是个不错的方法,但是很多情况下我们没办法将服务器设置为带有 SSL 的 Web 服务器。因此如果在登录系统中加入安全登录机制,则可以在没有 SSL 的 Web 服务器上实现安全登录。
要实现安全登录,可以采用下面三种方法,一种基于非对称加密算法,一种基于对称加密算法,最后一种基于散列算法。下面我们来分别讨论这三种方法。
非对称加密算法中,目前最常用的是 RSA 算法和 ECC(椭圆曲线加密)算法。要采用非对称加密算法实现安全登录的话,首先需要在客户端向服务器端请求登录页面时,服务器生成公钥和私钥,然后将公钥随登录页面一起传递给客户端浏览器,当用户输入完用户名密码点击登录时,登录页面中的 JavaScript 调用非对称加密算法对用户名和密码用用公钥进行加密。然后再提交到服务器端,服务器端利用私钥进行解密,再跟数据库中的用户名密码进行比较,如果一致,则登录成功,否则登录失败。
看上去很简单,但是这里有这样几个问题。目前 RSA 算法中,1024-2048 位的密钥被认为是安全的。如果密钥长度小于这个长度,则认为可以被破解。但这样的长度超过了程序设计语言本身所允许的数字运算范围,需要通过模拟来实现大数运算。而在 Web 系统的客户端,如果通过 JavaScript 来模拟大数运行的话,效率将会是很低的,因此要在客户端采用这样的密钥来加密数据的话,许多浏览器会发出执行时间过长,停止运行的警告。然而,解密或者密钥生成的时间相对于加密来说要更长。虽然解密和密钥生成是在服务器端执行的,但是如果服务器端是 PHP、ASP 这样的脚本语言的话,它们也将很难胜任这样的工作。ECC 算法的密钥长度要求比 RSA 算法要低一些,ECC 算法中 160 位的密钥长度被认为与 RSA 算法中 1024 位的密钥长度的安全性是等价的。虽然仍
然要涉及的模拟大数运算,但 ECC 算法的密钥长度的运算量还算是可以接受的,但是 ECC 算法比 RSA 算法要复杂的多,因此实现起来也很困难。
对称加密算法比非对称加密算法要快得多,但是对称加密算法需要数据发送方和接受方共用一个密钥,密钥是不能通过不安全的网络直接传递的,否则密钥和加密以后的数据如果同时监听到的话,入侵者就可以直接利用监听到的密钥来对加密后的信息进行解密了。
那是不是就不能通过对称加密算法实现安全登录呢?其实只要通过密钥交换算法就可以实现安全登录了,常用的密钥交换算法是 Diffie-Hellman 密钥交换算法。我们可以这样来实现密钥的安全传递,首先在客户端向服务器端请求登录页面时,服务器端生成一个大素数 p,它的本原根 g,另外生成一个随机数 Xa,然后计算出 Ya = gXa mod p,将 p、g、Ya 连同登录页面一起发送给客户端,然后客户端也生成一个随机数 Xb,计算 Yb = gXb mod p,然后再计算 K = YaXb mod p,现在 K 就是密钥,接下来就可以用 K 作密钥,用对称加密算法对用户输入进行加密了,然后将加密后的信息连同计算出来的 Yb 一同发送给服务器端,服务器端计算 K = YbXa mod p,这样就可以得到跟客户端相同的密钥 K 了,最后用客户端加密算法的相应解密算法,就可以在服务器端将加密信息进行解密了,信息解密以后进行比较,一致则登录成功,否则登录失败。需要注意的时候,这里服务器端生成的随机数 Xa 和客户端生成的随机数 Xb 都不传递给对方。传递的数据只有 p、g、Ya、Yb 和加密后的数据。
但是如果我们不采用加密算法而采用散列算法对登录密码进行处理的话,可以避免被直接解密出原文,但是如果直接采用 MD5 或者 SHA1 来对登录密码进行处理后提交的话,一旦入侵者监听到散列后的密码,则不需要解密出原文,直接将监听到的数据提交给服务器,就可以实现入侵的目的了。而且,目前 MD5 算法已被破解,SHA1 算法则被证明从理论上可破解,就算采用离线碰撞,也可以找出与原密码等价的密码来。所以直接采用 MD5 或者 SHA1 来对密码进行散列处理也是不可行的。
但是如果在散列算法中加入了密钥,情况就不一样了。hmac 算法正好作了这样的事情,下面我们来看看如何用 hmac 算法实现安全登录。首先在客户端向服务器端请求登录页面时,服务器端生成一个随机字符串,连同登录页面一同发送给客户端浏览器,当用户输入完用户名密码后,将密码采用 MD5 或者 SHA1 来生成散列值作为密钥,服务器端发送来的随机字符串作为消息数据,进行 hmac 运算。然后将结果提交给服务器。之所以要对用户输入的密码进行散列后再作为密钥,而不是直接作为密钥,是为了保证密钥足够长,而又不会太长。服务器端接受到客户端提交的数据后,将保存在服务器端的随机字符串和用户密码进行相同的运算,然后进行比较,如果结果一致,则认为登录成功,否则登录失败。当然如果不用 hmac 算法,直接将密码和服务器端生成的随机数合并以后再做 MD5 或者 SHA1,应该也是可以的。
这里客户端每次请求时服务器端发送的随机字符串都是不同的,因此即使入侵者监听到了这个随机字符串和加密后的提交的数据,它也无法再次提交相同的数据通过验证。而且通过监听到的数据也无法计算出密钥,所以也就无法伪造登录信息了。
对称和非对称加密算法不仅适用于登录验证,还适合用于最初的密码设置和以后密码修改的过程中,而散列算法仅适用于登录验证。但是散列算法要比对称和非对称加密算法效率高。
3.基于MD5的网页登陆安全认证详细设计3.1.网页登陆安全认证系统结构
图2.1 网页登陆安全认证系统结构图3.2.网页登陆安全认证相关文件
3.3.脚本详细设计
表2.3-1 get_ran_str.sh脚本设计
#!/bin/sh
a=`./random_string`
printf "" > md5_verify.log
awk -F ' ' "{txt=\"$a\"\$1\$2; system(\"printf \" txt \" | md5sum\")}" user.log | awk '{print "md5:"$1"\tstat:"}' >> md5_verify.log
echo -e "Content-Type: text/html\n"
printf "var random_str='"$a"';"
表2.3-2 verify_login.sh脚本设计
#!/bin/sh
MD5_VERIFY_FILE=./md5_verify.log
LOGIN_PAGE_URL=/testmd5.asp
PERMIT_JUMP_PAGE_URL=https://www.360docs.net/doc/c88996285.html,
alert(){
echo "
alert('$1');
window.location.href='$LOGIN_PAGE_URL';
"
}
echo -e "Content-Type: text/html\n"
#env | awk '{print $0 ""}'
if grep $md5 $MD5_VERIFY_FILE > /dev/null
then
if grep "$md5.*stat:1" $MD5_VERIFY_FILE > /dev/null
then
alert 'PID失效,请重新登录'
else
sed -i "/$md5/s/stat:.*/stat:1/g" $MD5_VERIFY_FILE
echo "
window.location.href='$PERMIT_JUMP_PAGE_URL';
"
fi
else
alert '用户名密码错误'
fi
3.4.日志文件(log文件)格式
表2.4-1 user.log文件内容格式
user:lvxin password:lvxin
user:lv password:lvxin
user:hello password:he
表中每一行记录一个用户,包括用户名、密码
表2.4-2 md5_verify.log文件内容格式
md5:07eab8c1668d793210f60c74c0b176f2 stat:1
md5:74e6a575852dbd6cc74f497af74f03e7 stat:
md5:9fe6941a9145733894454383769175a6 stat:
表中每一行表示对应user.log文件中的用户信息与get_ran_str.sh生成的随机串做MD5后的值,stat表示用户登录状态,如果是1,则表示用户已经使用该MD5值登陆过了,有verify_login.sh脚本判断,如果已经使用过了,则要求用户重新登录,重新进入登陆页并运行get_ran_str.sh,以更新MD5值。
4.登录页最小化范例
表3 login.html范例
function check_name_passwd(element){
var user= https://www.360docs.net/doc/c88996285.html,er.value;
var passwd = element.password.value;
if (user == "" || passwd == ""){
alert('Input Error!');
}else{
var
text=random_str+"user:"+user+"password:"+passwd;
var text_md5 = $.md5(text);
element.md5.value=text_md5;
}
https://www.360docs.net/doc/c88996285.html,er.value="";
element.password.value="";
return true;
}