您的位置:

滑动验证码的实现与安全性

一、滑动验证码的作用

滑动验证码最初是为了解决机器人或者脚本在网站上的恶意操作所产生的问题而出现。它通过普通验证码的数字或字符转化为操作行为,提示用户拖动滑块以完成验证。

滑动验证码的出现使得普通验证码的替代,用户需要繁琐地输入验证码的时代已经过去了。它无需用户手动输入,提高了用户体验,也有利于防范恶意操作或者攻击的出现。

同时,滑动验证码也能够用于用户身份认证时的二次验证或者应用于不安全环境下的安全验证。总体来看,滑动验证码的作用得到了极大的扩展和应用。

二、滑动验证码的实现

滑动验证码的实现有多种方法,比较常见的是前端JavaScript实现和后端Python实现。下面将对这两种实现方法进行介绍。

1.前端JavaScript实现

前端JavaScript实现滑动验证码的基本原理是通过鼠标操作得到用户的移动轨迹,对移动轨迹进行判断和处理,从而完成验证。

根据实现方法的不同,前端JavaScript可以将滑块转化成CSS动画,模拟拖拽操作,实时改变DOM元素位置等。接下来,我们看一个简单的实现例子:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>滑动验证码的实现</title>
</head>
<body>
<div id="slideTarget" style="background-color: #ccc;height: 50px;width: 300px;position: relative">
<div id="slideBar" style="background-color: #fff;height: 50px;width: 50px;position: absolute;left: 0;top:0"></div>
<div />
<script>
var slideTarget=document.getElementById("slideTarget");
var slideBar=document.getElementById("slideBar");
slideBar.onmousedown=function(e){
    var moveX=e.clientX-slideBar.offsetLeft;
    document.onmousemove=function(e){
        var x=e.clientX-moveX;
        if(x<0){
            x=0;
        }else if(x>(slideTarget.offsetWidth-slideBar.offsetWidth)){
            x=slideTarget.offsetWidth-slideBar.offsetWidth;
        }
        slideBar.style.left=x+'px';
    }
}
document.onmouseup=function(){
    document.onmousemove=null;
}
</script>
</body>
</html>

构建一个包含滑块和滑动轨迹的div,并通过前端JavaScript监听鼠标事件,完成滑块的移动和验证。通过鼠标按下和移动事件获取鼠标在屏幕中的位置,同时进行坐标的计算,并完成滑块的移动。最终,验证是否通过的判断方式则由具体的应用场景和需求进行决定。

2.后端Python实现

后端Python实现滑动验证码最基本的逻辑就是模拟用户进行拖动操作,来生成用户拖动滑块的轨迹。与前端JavaScript相比,后端Python实现滑动验证码主要应用于服务器端的后台处理和生成滑动图像的操作。

Python实现滑动验证码的具体流程为:先将一个滑块的图片进行切割,分成两部分(滑块部分和缺口部分)。在用户进行滑动过程中,服务器端要动态生成出一个随机的滑动图片,并对这张图片进行加噪声等处理,初始化该图像的滑块位置在图像的一侧,然后再通过一定的算法确定滑块的终点位置。当用户进行滑动操作时,由于拖拽的惯性,会超出滑块本身位置的范围,出现滑块与缺口之间有一定的误差。这个误差就是通过判断滑块和缺口之间的相对距离来完成验证的。下面是一个Python实现例子:

from PIL import Image, ImageDraw, ImageFont
import random
 
# 创建画布
def create_canvas():
    width = 300
    height = 180
    # 创建一个空白图片对象,背景为白色
    im = Image.new('RGB', (width, height), 'white')
    # 创建画笔对象
    draw = ImageDraw.Draw(im)
    return im, draw
 
# 绘制滑块
def draw_slider(im, draw):
    font = ImageFont.truetype('arial.ttf', 40)
    # 滑块的边长
    slider_side = 50
    # 滑块距左端的距离
    slider_left = random.randint(50, 150)
    # 滑块距上端的距离
    slider_top = random.randint(60, 110)
    # 绘制滑块
    draw.rectangle([slider_left, slider_top, slider_left + slider_side, slider_top + slider_side],
                   fill=(0, 0, 0), outline=(0, 0, 0), width=1)
    # 绘制文字
    draw.text((15, 20), u'请拖动滑块完成验证', font=font, fill=(0, 0, 0))
    return slider_left, slider_top
 
# 绘制缺口
def draw_gap(im, draw, slider_left, slider_top):
    gap = random.randint(40, 80)
    left = random.randint(0, 100)
    top = random.randint(0, 50)
    # 填充滑块缺口部分
    draw.rectangle([slider_left + left, slider_top + top, slider_left + left + gap, slider_top + top + 6],
                   fill=(0, 0, 0), outline=(0, 0, 0), width=1)
    return gap, left, top
 
# 开始拖动滑块的位置
def get_track(start, gap):
    track = []
    x, y = start, 0
    while x < 300 - 52:
        track.append(int(random.uniform(x, x + gap / 2)))
        x += int(random.uniform(4, 7))
        y += int(random.uniform(-1, 1))
    track.append(300 - 52)
    return track

Python实现的滑动验证码需要将绘制的验证码图像发送到前端,并通过前端JavaScript完成用户的验证。可以通过Ajax技术将所绘制好的图像数据发送到前端,用户进行验证操作后,再将操作结果与服务器端返回的数据进行比对,从而完成判定和验证。除此之外的滑动验证码实现还包括滑块和背景图形的特效处理、坐标生成算法等各种技巧,让验证码更加安全、实用和有趣。

三、滑动验证码的安全性

滑动验证码虽然解决了验证码手动输入的烦琐,但是在应用中也需要注意安全性的问题,滑动验证码的安全性主要体现在下面几个方面:

1.破解难度

对于一些普通的滑动验证码,只需要简单地实现一个模拟鼠标移动的程序就能够轻易地通过验证。用户设置密码、登录、支付等功能上需要加入判断因素,使得攻击者通过模拟用户信令来进行攻击的难度增大。

2.防刷策略

滑动验证码可以有效地防止机器人或脚本进行恶意攻击,但这并不是绝对的,有些登陆攻击代码可以通过分析目标网站来自定义鼠标路径。

3.破解方法分析

基于人为属性,鼠标轨迹存在原子性,一般都是有规律的,距离方差需要小;速度方差需要小,方向变化需要连续。当距离方差较大时,可能存在加速、骤停等操作,看起来像是作弊的行为。

同时,防破解还可以采用测试样本的随机性,通过调整阈值可很好地抵制目攻击,如果采取半监督或者是全监督的方法,包含大量样本数据,能够对生产样本进行模拟,也是可以有效保证滑动验证码的安全性。

总体来说,采用滑动验证码的目的是为保护网站的安全性。每一种方法都存在攻击与防御的关系,可以针对性的进行防御措施,增强滑动验证码的安全性。