GeeTest 极验验证

前台Html页面

    <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
    <script src="http://static.geetest.com/static/tools/gt.js"></script>
    <div style="margin:300px;" >
        <div id="yzm"></div>
        <button type="submit" id="login">Login</button>
    </div>

        <script type="text/javascript">

            $(function () {

                var handler = function (captchaObj) {
                    captchaObj.appendTo("#yzm");
                };

                $.ajax({

                    url: "GeetestCaptcha.aspx?action=Create",
                    type: "get",
                    dataType: "json",
                    success: function (data) {
                        initGeetest({
                            gt: data.gt,
                            challenge: data.challenge,
                            product: "embed‘",
                            offline: !data.success
                        }, handler);
                    }
                });

                $("#login").click(function () {

                    $.ajax({
                        url: "GeetestCaptcha.aspx?action=Check",
                        type: "post",
                        data:{
                            geetest_challenge: $(".geetest_challenge").val(),
                            geetest_validate: $(".geetest_validate").val(),
                            geetest_seccode: $(".geetest_seccode").val()
                        },
                        success: function (data) {
                            if (data == "ok") {
                                alert("ok");
                            }
                        }

                    });
                });

            });

        </script>

后台验证码处理

            if (Request["action"]==GeeTestHelper.Create)
            {
                Response.ContentType = "application/json";
                GeeTestHelper geetest = new GeeTestHelper("846e30599eb209b6aad0b8c2477fccb5", "f5a7e9d5bbc6b79bb1812dbfb5898215");
                String userID = "test";
                Byte gtServerStatus = geetest.preProcess(userID);
                Session[GeeTestHelper.gtServerStatusSessionKey] = gtServerStatus;
                Session["GeetestUserTest"] = userID;
                string s = geetest.getResponseStr();
                Response.Write(s);
                Response.End();
            }

            if (Request["action"]==GeeTestHelper.Check)
            {
                GeeTestHelper geetest = new GeeTestHelper("846e30599eb209b6aad0b8c2477fccb5", "f5a7e9d5bbc6b79bb1812dbfb5898215");
                Byte gt_server_status_code = (Byte)Session[GeeTestHelper.gtServerStatusSessionKey];
                String userID = (String)Session["GeetestUserTest"];
                int result = 0;
                String challenge = Request[GeeTestHelper.fnGeetestChallenge];
                String validate = Request[GeeTestHelper.fnGeetestValidate];
                String seccode = Request[GeeTestHelper.fnGeetestSeccode];
                if (gt_server_status_code == 1)
                {
                    result = geetest.enhencedValidateRequest(challenge, validate, seccode, userID);
                }
                else result = geetest.failbackValidateRequest(challenge, validate, seccode);
                if (result == 1) Response.Write("ok");
                else Response.Write("error");
            }

GeeTestHelper

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;

public class GeeTestHelper
{
    /// <summary>
    /// SDK版本号
    /// </summary>
    public const String version = "3.2.0";

    public const string Create = "Create";
    public const string Check = "Check";
    /// <summary>
    /// SDK开发语言
    /// </summary>
    public const String sdkLang = "csharp";
    /// <summary>
    /// 极验验证API URL
    /// </summary>
    protected const String apiUrl = "http://api.geetest.com";
    /// <summary>
    /// register url
    /// </summary>
    protected const String registerUrl = "/register.php";
    /// <summary>
    /// validate url
    /// </summary>
    protected const String validateUrl = "/validate.php";
    /// <summary>
    /// 极验验证API服务状态Session Key
    /// </summary>
    public const String gtServerStatusSessionKey = "gt_server_status";
    /// <summary>
    /// 极验验证二次验证表单数据 Chllenge
    /// </summary>
    public const String fnGeetestChallenge = "geetest_challenge";
    /// <summary>
    /// 极验验证二次验证表单数据 Validate
    /// </summary>
    public const String fnGeetestValidate = "geetest_validate";
    /// <summary>
    /// 极验验证二次验证表单数据 Seccode
    /// </summary>
    public const String fnGeetestSeccode = "geetest_seccode";
    private String userID = "";
    private String responseStr = "";
    private String captchaID = "";
    private String privateKey = "";

    /// <summary>
    /// 验证成功结果字符串
    /// </summary>
    public const int successResult = 1;
    /// <summary>
    /// 证结失败验果字符串
    /// </summary>
    public const int failResult = 0;
    /// <summary>
    /// 判定为机器人结果字符串
    /// </summary>
    public const String forbiddenResult = "forbidden";

    /// <summary>
    /// GeetestLib构造函数
    /// </summary>
    /// <param name="publicKey">极验验证公钥</param>
    /// <param name="privateKey">极验验证私钥</param>
    public GeeTestHelper(String publicKey, String privateKey)
    {
        this.privateKey = privateKey;
        this.captchaID = publicKey;
    }
    private int getRandomNum()
    {
        Random rand = new Random();
        int randRes = rand.Next(100);
        return randRes;
    }

    /// <summary>
    /// 验证初始化预处理
    /// </summary>
    /// <returns>初始化结果</returns>
    public Byte preProcess()
    {
        if (this.captchaID == null)
        {
            Console.WriteLine("publicKey is null!");
        }
        else
        {
            String challenge = this.registerChallenge();
            if (challenge.Length == 32)
            {
                this.getSuccessPreProcessRes(challenge);
                return 1;
            }
            else
            {
                this.getFailPreProcessRes();
                Console.WriteLine("Server regist challenge failed!");
            }
        }

        return 0;

    }
    public Byte preProcess(String userID)
    {
        if (this.captchaID == null)
        {
            Console.WriteLine("publicKey is null!");
        }
        else
        {
            this.userID = userID;
            String challenge = this.registerChallenge();
            if (challenge.Length == 32)
            {
                this.getSuccessPreProcessRes(challenge);
                return 1;
            }
            else
            {
                this.getFailPreProcessRes();
                Console.WriteLine("Server regist challenge failed!");
            }
        }

        return 0;

    }
    public String getResponseStr()
    {
        return this.responseStr;
    }
    /// <summary>
    /// 预处理失败后的返回格式串
    /// </summary>
    private void getFailPreProcessRes()
    {
        int rand1 = this.getRandomNum();
        int rand2 = this.getRandomNum();
        String md5Str1 = this.md5Encode(rand1 + "");
        String md5Str2 = this.md5Encode(rand2 + "");
        String challenge = md5Str1 + md5Str2.Substring(0, 2);
        this.responseStr = "{" + string.Format(
             "\"success\":{0},\"gt\":\"{1}\",\"challenge\":\"{2}\"", 0,
            this.captchaID, challenge) + "}";
    }
    /// <summary>
    /// 预处理成功后的标准串
    /// </summary>
    private void getSuccessPreProcessRes(String challenge)
    {
        challenge = this.md5Encode(challenge + this.privateKey);
        this.responseStr = "{" + string.Format(
            "\"success\":{0},\"gt\":\"{1}\",\"challenge\":\"{2}\"", 1,
            this.captchaID, challenge) + "}";
    }
    /// <summary>
    /// failback模式的验证方式
    /// </summary>
    /// <param name="challenge">failback模式下用于与validate一起解码答案, 判断验证是否正确</param>
    /// <param name="validate">failback模式下用于与challenge一起解码答案, 判断验证是否正确</param>
    /// <param name="seccode">failback模式下,其实是个没用的参数</param>
    /// <returns>验证结果</returns>
    public int failbackValidateRequest(String challenge, String validate, String seccode)
    {
        if (!this.requestIsLegal(challenge, validate, seccode)) return GeeTestHelper.failResult;
        String[] validateStr = validate.Split(‘_‘);
        String encodeAns = validateStr[0];
        String encodeFullBgImgIndex = validateStr[1];
        String encodeImgGrpIndex = validateStr[2];
        int decodeAns = this.decodeResponse(challenge, encodeAns);
        int decodeFullBgImgIndex = this.decodeResponse(challenge, encodeFullBgImgIndex);
        int decodeImgGrpIndex = this.decodeResponse(challenge, encodeImgGrpIndex);
        int validateResult = this.validateFailImage(decodeAns, decodeFullBgImgIndex, decodeImgGrpIndex);
        return validateResult;
    }
    private int validateFailImage(int ans, int full_bg_index, int img_grp_index)
    {
        const int thread = 3;
        String full_bg_name = this.md5Encode(full_bg_index + "").Substring(0, 10);
        String bg_name = md5Encode(img_grp_index + "").Substring(10, 10);
        String answer_decode = "";
        for (int i = 0; i < 9; i++)
        {
            if (i % 2 == 0) answer_decode += full_bg_name.ElementAt(i);
            else if (i % 2 == 1) answer_decode += bg_name.ElementAt(i);
        }
        String x_decode = answer_decode.Substring(4);
        int x_int = Convert.ToInt32(x_decode, 16);
        int result = x_int % 200;
        if (result < 40) result = 40;
        if (Math.Abs(ans - result) < thread) return GeeTestHelper.successResult;
        else return GeeTestHelper.failResult;
    }
    private Boolean requestIsLegal(String challenge, String validate, String seccode)
    {
        if (challenge.Equals(string.Empty) || validate.Equals(string.Empty) || seccode.Equals(string.Empty)) return false;
        return true;
    }

    /// <summary>
    /// 向gt-server进行二次验证
    /// </summary>
    /// <param name="challenge">本次验证会话的唯一标识</param>
    /// <param name="validate">拖动完成后server端返回的验证结果标识字符串</param>
    /// <param name="seccode">验证结果的校验码,如果gt-server返回的不与这个值相等则表明验证失败</param>
    /// <returns>二次验证结果</returns>
    public int enhencedValidateRequest(String challenge, String validate, String seccode)
    {
        if (!this.requestIsLegal(challenge, validate, seccode)) return GeeTestHelper.failResult;
        if (validate.Length > 0 && checkResultByPrivate(challenge, validate))
        {
            String query = "seccode=" + seccode + "&sdk=csharp_" + GeeTestHelper.version;
            String response = "";
            try
            {
                response = postValidate(query);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            if (response.Equals(md5Encode(seccode)))
            {
                return GeeTestHelper.successResult;
            }
        }
        return GeeTestHelper.failResult;
    }
    public int enhencedValidateRequest(String challenge, String validate, String seccode, String userID)
    {
        if (!this.requestIsLegal(challenge, validate, seccode)) return GeeTestHelper.failResult;
        if (validate.Length > 0 && checkResultByPrivate(challenge, validate))
        {
            String query = "seccode=" + seccode + "&user_id=" + userID + "&sdk=csharp_" + GeeTestHelper.version;
            String response = "";
            try
            {
                response = postValidate(query);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            if (response.Equals(md5Encode(seccode)))
            {
                return GeeTestHelper.successResult;
            }
        }
        return GeeTestHelper.failResult;
    }
    private String readContentFromGet(String url)
    {
        try
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Timeout = 20000;
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            String retString = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();
            return retString;
        }
        catch
        {
            return "";
        }

    }
    private String registerChallenge()
    {
        String url = "";
        if (string.Empty.Equals(this.userID))
        {
            url = string.Format("{0}{1}?gt={2}", GeeTestHelper.apiUrl, GeeTestHelper.registerUrl, this.captchaID);
        }
        else
        {
            url = string.Format("{0}{1}?gt={2}&user_id={3}", GeeTestHelper.apiUrl, GeeTestHelper.registerUrl, this.captchaID, this.userID);
        }
        string retString = this.readContentFromGet(url);
        return retString;
    }
    private Boolean checkResultByPrivate(String origin, String validate)
    {
        String encodeStr = md5Encode(privateKey + "geetest" + origin);
        return validate.Equals(encodeStr);
    }
    private String postValidate(String data)
    {
        String url = string.Format("{0}{1}", GeeTestHelper.apiUrl, GeeTestHelper.validateUrl);
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = Encoding.UTF8.GetByteCount(data);
        // 发送数据
        Stream myRequestStream = request.GetRequestStream();
        byte[] requestBytes = System.Text.Encoding.ASCII.GetBytes(data);
        myRequestStream.Write(requestBytes, 0, requestBytes.Length);
        myRequestStream.Close();

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        // 读取返回信息
        Stream myResponseStream = response.GetResponseStream();
        StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
        string retString = myStreamReader.ReadToEnd();
        myStreamReader.Close();
        myResponseStream.Close();

        return retString;

    }
    private int decodeRandBase(String challenge)
    {
        String baseStr = challenge.Substring(32, 2);
        List<int> tempList = new List<int>();
        for (int i = 0; i < baseStr.Length; i++)
        {
            int tempAscii = (int)baseStr[i];
            tempList.Add((tempAscii > 57) ? (tempAscii - 87)
                : (tempAscii - 48));
        }
        int result = tempList.ElementAt(0) * 36 + tempList.ElementAt(1);
        return result;
    }
    private int decodeResponse(String challenge, String str)
    {
        if (str.Length > 100) return 0;
        int[] shuzi = new int[] { 1, 2, 5, 10, 50 };
        String chongfu = "";
        Hashtable key = new Hashtable();
        int count = 0;
        for (int i = 0; i < challenge.Length; i++)
        {
            String item = challenge.ElementAt(i) + "";
            if (chongfu.Contains(item)) continue;
            else
            {
                int value = shuzi[count % 5];
                chongfu += item;
                count++;
                key.Add(item, value);
            }
        }
        int res = 0;
        for (int i = 0; i < str.Length; i++) res += (int)key[str[i] + ""];
        res = res - this.decodeRandBase(challenge);
        return res;
    }
    private String md5Encode(String plainText)
    {
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
        string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(plainText)));
        t2 = t2.Replace("-", "");
        t2 = t2.ToLower();
        return t2;
    }

}
时间: 2024-10-05 07:56:42

GeeTest 极验验证的相关文章

GEETEST极验召集互联网大佬齐聚光谷,共同探讨交互安全问题

全球互联网技术在飞速发展的同时,网络安全事件也随之频发.除了直接带来经济损失的网络恶意攻击之外,企业在多个方面也遭受着不同程度的网络恶意攻击,包括品牌形象.管理时间.企业竞争力.客户成交量.用户行为等. 极验自2012年成立以来, 一直专注于利用人工智能技术解决日益严峻的互联网交互安全问题.为了更好的帮助企业应对日益严峻的交互安全形势,极验于9月14日举办的以"新视角.新安全"为主题的线下沙龙在光谷创业咖啡举办. 本次沙龙聚集了盛天网络.斗鱼TV.九州通.长江证券.泰康在线.楚天云.卓

极客验证官方demo构建使用及代码分析

#什么是极客验证? 官方定义:极验验证是一种在计算机领域用于区分自然人和机器人的,通过简单集成的方式,为开发者提供安全.便捷的云端验证服务. #使用命令从github上获取: git clone https://github.com/GeeTeam/gt3-java-sdk.git #使用idea搭建sdk工程: >>导入已有的工程: >>选择从git克隆的项目 >>选择Project Structure 设置 >>选择工程gt3-java-sdk >

极验3.0滑动拼图验证的使用--java

[ 前言: 在登录其他网站的时候,看到有个滑动拼图的验证觉得挺好玩的,以前做一个图片验证的小demo,现在发现很多网站都开始流行滑动拼图的验证了,今天也想自己动手来弄一个. 废话不多说,开始撸起来! ] 第一步:到官网把sdk的demo下载下来 https://docs.geetest.com/install/deploy/server/java/ 第二步:在自己项目上做测试,自己搭个SSM项目这个不用我多说了. 从官网上会下载一个gt3-java-sdk的文件夹,我只用到了其中的三个文件:lo

极验高并发验证服务背后的技术实现

极验目前的用户超过7万家网站,日均验证量1亿次,作为一家专注于验证安全服务的公司,极验所要面临的并发压力主要表现在以下几点: 日益增加的用户并发量. 验证请求是全动态过程,不能够进行缓存. 每一次请求都会造成数据库的读写. 处理请求需要耗费CPU大量的时间进行模型的计算. 作为抗击黑产的第一线,可能遭到黑产的攻击. 那么极验是如何做到,既保证用户的验证需求量,又尽量快速响应用户的验证请求,还能够扛得住黑产的攻击呢?极验主要从三个方面来解决高并发问题. 降低并发的开销 利用协程处理并发,我们熟知的

极验验证码的破解4-执行破解

经过以上的铺垫,我们就差最后一步了-破解!首选我们来分析一下要做的事情: 1.加载包含验证码的页面,当然是用我们前面讲的phantomaJS来加载啦,因为极验验证码是依赖于js渲染的,我们必须等页面完全渲染完成后再执行拖动 2.收集一些页面的参数发送到java后台服务计算滑块的目标位移并接受结果 3.通过js模拟鼠标事件来实现滑块的移动 4.输出验证结果 好,让我们一步步来讲解如果实现上面的目标. 我们首先新建一个js文件,就叫做geetest_refresh.js好了,我们首先写一些样板代码,

破解极验滑动验证码

阅读目录 一 介绍 二 实现 三 说明 一 介绍 一些网站会在正常的账号密码认证之外加一些验证码,以此来明确地区分人/机行为,从一定程度上达到反爬的效果,对于简单的校验码Tesserocr就可以搞定,如下 但一些网站加入了滑动验证码,最典型的要属于极验滑动认证了,极验官网:http://www.geetest.com/,下图是极验的登录界面 现在极验验证码已经更新到了 3.0 版本,截至 2017 年 7 月全球已有十六万家企业正在使用极验,每天服务响应超过四亿次,广泛应用于直播视频.金融服务.

Django中使用geetest实现滑动验证

下载第三方模块 导入模块social-auth-app-django 和geetest 提前去官网下载gt.js或者引入http://static.geetest.com/static/tools/gt.js pip install social-auth-app-django pip install geetest 在django引用 1.目录结构 2.html层 <!DOCTYPE html> <html lang="en"> <head> &l

极验验证码 破解

本文主要提供目前极验的识别思路. 极验验证码主要分为4步. 1/ 还原验证图片.通过分析CSS,发现是固定位置,把一张图片分成若干份,按照指定顺序重新排列,所以难度不大. 2/ 还原好图片后,找出2张图片的差异,即bg(验证图)和fullbg(全图).这个难度也不大,按像素或者按块去扫描.设定一个阈值,当2个图片块或像素的差异值高于这个阈值的时候,就横向向右再扫描几个像素,例如10个,如果这10个像素里面有7个都高于这个像素.那个这个像素所在图片的X坐标,就是我们要的坐标点.根据这种方式,识别坐

极验验证码的破解3-模拟浏览器渲染

前面我们介绍了如何求解极验验证码的滑块目标位移,下面我就就要开始实施拖动滑块破解了.因为我们采取的是模拟人的行为操作,而极验验证码都是js渲染的,因此我们需要一个工具来帮我们完成这个渲染过程得到一个完整的页面,否则一切都是空谈.这里我将使用casperJs+phantomJs来实现目标. phantomJs号称一个headless的浏览器,也就是包含浏览器内核但是没有界面的浏览器,它是跨平台的,安装很简单,解压到一个目录即可. casperJs是基于phantomJs的封装,提供了更友好的api