len:7398
len:13
len:4
len:0
len:0
len:0
len:12
len:6
len:0
len:2
len:6
zz22zz技术论坛
首页| 论坛| 消息
主题:二次登陆验证之口令卡验证
瓜牛发表于 2011-11-02 18:44
前言:我这个人还是比较懒的,所以很多东西也懒的整理,今天分享下之前做的一个口令卡二次登陆验证。这个东西对于单一密码的安全性还是有一定提高的,当然肯定也是存在问题的。
基本流程就是后台添加需要二次验证的用户后系统会生成对应用户的一个数据序列,将序列储存到数据库中,而用户的展现形式则是一张二维口令卡。前台登录的时候更改原论坛提交流程,首先发送包含用户名的一个请求发送到该插件前台处理文件,程序根据用户名检索数据库,返回该用户是否需要口令验证。如果需要验证,则生成一个口令卡坐标及生成一个储存坐标的cookie,登录页面则弹出一个对话框,提示用户输入口令卡上对应坐标的散列。完成后转回到页面提交表单流程,提交登录表单。登录程序验证完合法用户以后,继而验证用户输入散列与cookie里储存坐标产生的散列是否一致,如不一致则登录不成功!
以下是后台生成口令卡核心代码。
public function createCard($codeNum = '3') { //生成口令卡
$arr = array();
for ($x = 1; $x
{$key}
{$v}

执行的结果如下

以下是前台请求时生成的字母坐标并生成一个cookie
public function outPutCode() {//随机生成用户验证序列并生成cookie
$num = array();
$x = $num['x'] = array(rand(1, 10), rand(1, 8));
$y = $num['y'] = array(rand(1, 8), rand(1, 10));
Cookie('cardhash', StrCode($this->timestamp."\t\t".serialize($num))); //储存的是一个坐标序列化字串
$cardNum = array(chr(64 + $x[0]). chr(74 + $x[1]), chr(74 + $y[0]). chr(64 + $y[1]));
return implode(':',$cardNum);
}

接下来我们要做的是修改登录页面,使用户登录时产生二次验证对话框。
打开wind/login.htm在用户登录表单里面加一个onsubmit事件用于提交前验证是否需要口令卡验证。函数名为checklogin
函数代码如下
function checklogin(f) {
//f.submit.disabled = true;
if (f.pwuser.value == '' || f.pwpwd.value == '') {
alert('用户名或密码不能为空');
return false;
}
login_user = f.pwuser.value;
ajax.send("hack.php?H_name=passcard&action=ajax&do=checkuser&username=" + encodeURIComponent(login_user) + '&nowtime=' + new Date().getTime(), '', function(){
var rText = ajax.request.responseText.split('|');
if (rText[0] == 'needcheck') {
showDialog({type:'confirm',message:'口令卡验证: ' + rText[1] + '',okText:'验证登陆',onOk:function() {
if (getObj('cardcode').value == '') {
alert('请正确输入验证码');
} else {
getObj('form_cardnum').value = getObj('cardcode').value;
//console.log(f.submit)
f.submit();
}
}});
//f.submit.disabled = false;
} else if (rText[0] == 'pass' || rText[0] == 'nouser') {
f.submit();
}
});
return false;
}

如需要验证则会弹出以下对话框
如果输入对应的散列则进入正常密码验证流程,当系统调用uc_click.php获取用户信息之后进入口令卡验证流程。
所在文件 require/checkpass.php

require_once(R_P . 'uc_client/uc_client.php');
$uc_user = uc_user_login($username, $password, $lgt);
if ($uc_user['status'] == -1) {
$GLOBALS['errorname'] = $username;
//Showmsg('user_not_exists');
return 'user_not_exists';
}
//以上是确定用户是存在的
//口令卡验证
$card = new passcard;
if ($codeinfo = $card->getCard($uc_user['uid'])) { //如果已经绑定口令卡则进入验证流程
if (!$cardnum) { //$cardnum是修改checkpass()函数,传入的一个参数,由loging.php接收。
return '您的账户需要口令卡验证,请返回重新填写';
}
$cookieData = explode("\t", StrCode(GetCookie('cardhash'), 'DECODE'));
if($timestamp - $cookieData[0] > 1800) {
Cookie($cookieName, '', 0);
return '口令密码超时,请刷新页面重试';
}
$cookiehash = unserialize($cookieData[2]);//反序列化,对应之前序列化存储
if (!$card->checkHash($codeinfo['cardcode'], $cardnum, $cookiehash['x'], $cookiehash['y'])) {<

浏览大图

浏览大图
下一页 (1/3)
回帖(2):
2楼:牛逼
1楼:顶

全部回帖(2)»
最新回帖
收藏本帖
发新帖