热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP对验证码的认证过程防止机器注册-PHP源码

PHP对验证码的认证过程文章重点为告诉各位如何防止机器注册这个问题了,下面我们一起来看看例子,希望对各位有帮助。
PHP对验证码的认证过程文章重点为告诉各位如何防止机器注册这个问题了,下面我们一起来看看例子,希望对各位有帮助。


这段时间在写php脚本,接触到web前端以及web安全问题比较多,这时给大家简单地谈一下我们网站验证码的验证过程及其安全问题。

从三个方面去谈一下关于验证码的使用:验证码的生成,验证的过程,验证中注意的安全问题。

验证码的生成,首先还是要说说验证码的作用。众所周知,验证码的存在,是为了防止一些机器,或是刷恶意留言、无限注册用户或是暴力破解账号密码。现在普通的验证码是由一个php脚本生成的,比如打开我们emlog的include/lib/文件夹,底下有个checkcode.php,这就是生成验证码的脚本。

我们可以简单看一下它的代码:
session_start();

$randCode = '';
$chars = 'abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPRSTUVWXYZ23456789';
for ( $i = 0; $i <5; $i++ ){
$randCode .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}

$_SESSION['code'] = strtoupper($randCode);

$img = imagecreate(70,22);
$bgColor = isset($_GET['mode']) && $_GET['mode'] == 't' ? imagecolorallocate($img,245,245,245) : imagecolorallocate($img,255,255,255);
$pixColor = imagecolorallocate($img,mt_rand(30, 180), mt_rand(10, 100), mt_rand(40, 250));

for($i = 0; $i <5; $i++){
$x = $i * 13 + mt_rand(0, 4) - 2;
$y = mt_rand(0, 3);
$text_color = imagecolorallocate($img, mt_rand(30, 180), mt_rand(10, 100), mt_rand(40, 250));
imagechar($img, 5, $x + 5, $y + 3, $randCode[$i], $text_color);
}
for($j = 0; $j <60; $j++){
$x = mt_rand(0,70);
$y = mt_rand(0,22);
imagesetpixel($img,$x,$y,$pixColor);
}

header('Content-Type: image/png');
imagepng($img);
imagedestroy($img);

第一个for循环在$chars这个字符串中随机取了5个字符,这实际上就是我们的真实验证码。然后我们可以看到:$_SESSION['code'] = strtoupper($randCode); 他把我们的验证码转换成大写赋值到session里了。

有的朋友要问,问什么赋值到SESSION里了不赋值到COOKIE里。这就说明你对他们二者关系不了解。COOKIE和session都作为网站临时保存客户端相关信息的一个“容器”,但是COOKIE是保存在客户端里的,也就是网站的访问者可以随意查看和修改COOKIE里的内容,那就没有验证码存在的意义了,因为用户可以直接从COOKIE中读到验证码,当然机器也可以。而session是保存在服务器上的内容,我生成好的验证码,用户不可能读取到。

再看源码,后面的两个循环分别是生成彩色的带验证码的图片和在图片上加噪点。是为了加大机器识别验证码的难度。最后我们看到,header('Content-Type: image/png'); 把我们这个页面定义成为图片的格式。

这样,我们就可以用html代码来让验证码显示出来:


类似这样:
那么验证的过程就是,我们首先生成5个随机字符,保存到session里。然后把这5个字符画成一个图片给用户看,让用户识别,填写在表单里提交后和我们session里的验证码比对。

其实就是这么简单。

最后来说说验证码的安全性。我们emlog和wordpress其实验证码并不是很强大,我们这个简单的验证码可以写一个小脚本很容易地识别,所以并不适合比较大型的网站使用。像类似腾讯、百度这种网站的验证码很多字符能旋转、扭曲,并且背影上的干扰物更多,甚至是中文验证码。不过对于小型网站来说,普通等级的验证码足矣防范很多刷评论的机器。

还有一点很重要,注意验证码使用过后要记住删除相应的session。否则验证码就失去了其意义,这也是我之前犯过的错误。

为什么这么说。作为一个正常用户,我们每访问一次需要填写验证码的页面,生成验证码的脚本都会执行一次,也就说会生成一个新验证码赋值到session里,没有任何问题。但对于一个机器(或一个暴力破解密码脚本),它第一次访问需要填写验证码的页面,然后在session中得到一个验证码,它以后就不用再次访问这个页面了。直接把第一次的数据包更改并再次发送即可,于是,如果没有清除session的网站,每次的验证码都和第一次相同,也就丧失了验证码的本来作用。

这是我们做网站需要注意的地方。希望大家在写程序的时候多注意网站的安全性,避免在网站发布后出现问题

通过网上的一些实例,拼凑出一个验证码登陆测试程序。详细代码如下:

生成验证码程序ttt.php。通过random生成随机数,然后保存在session里:


login.htm页面











请输入验证码







验证码:






login.php

session_start();
$name = $_POST['user'];
$password = $_POST['passwd'];
$auth = $_POST['auth'];
#require("db.php");
#$db = new db();
#$sql = "select * from user where name = '$name' and password = '$password'";
#$result = $db->query($sql);
if($_SESSION['seccode'] == $auth)
{
#$_SESSION['user'] = $name;
#$_SESSION['passwd'] = $password;
# header("Location: main.php");
#echo ("登录成功!");

$_SESSION['seccode']='';
print '
';
}else
{
print '
';
}
?>

ttt.php验证码生成程序

session_start();

function random($length, $numeric = 0) {
mt_srand((double)microtime() * 1000000);
if($numeric) {
$hash = sprintf('%0'.$length.'d', mt_rand(0, pow(10, $length) - 1));
} else {
$hash = '';
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
$max = strlen($chars) - 1;
for($i = 0; $i <$length; $i++) {
$hash .= $chars[mt_rand(0, $max)];
}
}
return $hash;
}

#if(preg_replace("/https?:\/\/([^\:\/]+).*/i", "\\1", $_SERVER['HTTP_REFERER']) != preg_replace("/([^\:]+).*/", "\\1", $_SERVER['HTTP_HOST'])) {
# exit('Access Denied');
#}

//if($_GET['update']) {
$seccode = random(4, 1);
//}

#if($seccode <1 || $seccode > 9999) {
# exit('Access Denied');
#}

$_SESSION['seccode'] = $seccode;
$seccode = sprintf('%04d', $seccode);

if(!$nocacheheaders) {
@header("Expires: -1");
@header("Cache-Control: no-store, private, post-check=0, pre-check=0, max-age=0", FALSE);
@header("Pragma: no-cache");
}

if(function_exists('imagecreate') && function_exists('imagecolorset') && function_exists('imagecopyresized') && function_exists('imagecolorallocate') && function_exists('imagesetpixel') && function_exists('imagechar') && function_exists('imagecreatefromgif') && function_exists('imagepng')) {

$im = imagecreate(62, 25);
$backgroundcolor = imagecolorallocate ($im, 255, 255, 255);

$numorder = array(1, 2, 3, 4);
shuffle($numorder);
$numorder = array_flip($numorder);

for($i = 1; $i <= 4; $i++) {
$imcodefile = 'seccode/'.$seccode[$numorder[$i]].'.gif';
$x = $numorder[$i] * 13 + mt_rand(0, 4) - 2;
$y = mt_rand(0, 3);
if(file_exists($imcodefile)) {
$imcode = imagecreatefromgif($imcodefile);
$data = getimagesize($imcodefile);
imagecolorset($imcode, 0 ,mt_rand(50, 255), mt_rand(50, 128), mt_rand(50, 255));
imagecopyresized($im, $imcode, $x, $y, 0, 0, $data[0] + mt_rand(0, 6) - 3, $data[1] + mt_rand(0, 6) - 3, $data[0], $data[1]);
} else {
$text_color = imagecolorallocate($im, mt_rand(50, 255), mt_rand(50, 128), mt_rand(50, 255));
imagechar($im, 5, $x + 5, $y + 3, $seccode[$numorder[$i]], $text_color);
}
}

$linenums = mt_rand(10, 32);
for($i=0; $i <= $linenums; $i++) {
$linecolor = imagecolorallocate($im, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
$linex = mt_rand(0, 62);
$liney = mt_rand(0, 25);
imageline($im, $linex, $liney, $linex + mt_rand(0, 4) - 2, $liney + mt_rand(0, 4) - 2, $linecolor);
}

for($i=0; $i <= 64; $i++) {
$pointcolor = imagecolorallocate($im, mt_rand(50, 255), mt_rand(50, 255), mt_rand(50, 255));
imagesetpixel($im, mt_rand(0, 62), mt_rand(0, 25), $pointcolor);
}

$bordercolor = imagecolorallocate($im , 150, 150, 150);
imagerectangle($im, 0, 0, 61, 24, $bordercolor);

header('Content-type: image/png');
imagepng($im);
imagedestroy($im);

} else {

$numbers = array
(
0 => array('3c','66','66','66','66','66','66','66','66','3c'),
1 => array('1c','0c','0c','0c','0c','0c','0c','0c','1c','0c'),
2 => array('7e','60','60','30','18','0c','06','06','66','3c'),
3 => array('3c','66','06','06','06','1c','06','06','66','3c'),
4 => array('1e','0c','7e','4c','2c','2c','1c','1c','0c','0c'),
5 => array('3c','66','06','06','06','7c','60','60','60','7e'),
6 => array('3c','66','66','66','66','7c','60','60','30','1c'),
7 => array('30','30','18','18','0c','0c','06','06','66','7e'),
8 => array('3c','66','66','66','66','3c','66','66','66','3c'),
9 => array('38','0c','06','06','3e','66','66','66','66','3c')
);

for($i = 0; $i <10; $i++) {
for($j = 0; $j <6; $j++) {
$a1 = substr('012', mt_rand(0, 2), 1).substr('012345', mt_rand(0, 5), 1);
$a2 = substr('012345', mt_rand(0, 5), 1).substr('0123', mt_rand(0, 3), 1);
mt_rand(0, 1) == 1 ? array_push($numbers[$i], $a1) : array_unshift($numbers[$i], $a1);
mt_rand(0, 1) == 0 ? array_push($numbers[$i], $a1) : array_unshift($numbers[$i], $a2);
}
}

$bitmap = array();
for($i = 0; $i <20; $i++) {
for($j = 0; $j <4; $j++) {
$n = substr($seccode, $j, 1);
$bytes = $numbers[$n][$i];
$a = mt_rand(0, 14);
switch($a) {
case 1: str_replace('9', '8', $bytes); break;
case 3: str_replace('c', 'e', $bytes); break;
case 6: str_replace('3', 'b', $bytes); break;
case 8: str_replace('8', '9', $bytes); break;
case 0: str_replace('e', 'f', $bytes); break;
}
array_push($bitmap, $bytes);
}
}

for($i = 0; $i <8; $i++) {
$a = substr('012', mt_rand(0, 2), 1) . substr('012345', mt_rand(0, 5), 1);
array_unshift($bitmap, $a);
array_push($bitmap, $a);
}

$image = pack('H*', '424d9e000000000000003e000000280000002000000018000000010001000000'.
'0000600000000000000000000000000000000000000000000000FFFFFF00'.implode('', $bitmap));

header('Content-Type: image/bmp');
echo $image;

}

?>

推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 本文介绍了Java的集合及其实现类,包括数据结构、抽象类和具体实现类的关系,详细介绍了List接口及其实现类ArrayList的基本操作和特点。文章通过提供相关参考文档和链接,帮助读者更好地理解和使用Java的集合类。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 本文介绍了一种图片处理应用,通过固定容器来实现缩略图的功能。该方法可以实现等比例缩略、扩容填充和裁剪等操作。详细的实现步骤和代码示例在正文中给出。 ... [详细]
  • 本文介绍了Cocos2dx学习笔记中的更新函数scheduleUpdate、进度计时器CCProgressTo和滚动视图CCScrollView的用法。详细介绍了scheduleUpdate函数的作用和使用方法,以及schedule函数的区别。同时,还提供了相关的代码示例。 ... [详细]
author-avatar
xaony23625
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有