├── demo
├── GeetestConfig.cs
├── Web.config
├── getcaptcha.aspx
├── getcaptcha.aspx.designer.cs
├── getcaptcha.aspx.cs
├── index.aspx.designer.cs
├── Properties
│ └── AssemblyInfo.cs
├── Web.Debug.config
├── Web.Release.config
├── index.aspx.cs
├── index.aspx
└── demo.csproj
├── src
└── GeetestSDK
│ ├── GeetestSDK
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── GeetestSDK.csproj
│ └── GeetestLib.cs
│ └── GeetestSDK.sln
├── README.rst
└── .gitignore
/demo/GeetestConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 |
6 | namespace demo
7 | {
8 | public class GeetestConfig
9 | {
10 | public const String publicKey = "b46d1900d0a894591916ea94ea91bd2c";
11 | public const String privateKey = "36fc3fe98530eea08dfc6ce76e3d24c4";
12 | }
13 | }
--------------------------------------------------------------------------------
/demo/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
--------------------------------------------------------------------------------
/demo/getcaptcha.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="getcaptcha.aspx.cs" Inherits="demo.GetCaptcha" %>
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/demo/getcaptcha.aspx.designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | // <自动生成>
3 | // 此代码由工具生成。
4 | //
5 | // 对此文件的更改可能导致不正确的行为,如果
6 | // 重新生成代码,则所做更改将丢失。
7 | // 自动生成>
8 | //------------------------------------------------------------------------------
9 |
10 | namespace demo {
11 |
12 |
13 | public partial class GetCaptcha {
14 |
15 | ///
16 | /// form1 控件。
17 | ///
18 | ///
19 | /// 自动生成的字段。
20 | /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
21 | ///
22 | protected global::System.Web.UI.HtmlControls.HtmlForm form1;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/demo/getcaptcha.aspx.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 | using System.Web.UI;
6 | using System.Web.UI.WebControls;
7 | using GeetestSDK;
8 |
9 | namespace demo
10 | {
11 | public partial class GetCaptcha : System.Web.UI.Page
12 | {
13 | protected void Page_Load(object sender, EventArgs e)
14 | {
15 | Response.ContentType = "application/json";
16 | Response.Write(getCaptcha());
17 | Response.End();
18 | }
19 | private String getCaptcha()
20 | {
21 | GeetestLib geetest = new GeetestLib(GeetestConfig.publicKey, GeetestConfig.privateKey);
22 | String userID = "test";
23 | Byte gtServerStatus = geetest.preProcess(userID);
24 | Session[GeetestLib.gtServerStatusSessionKey] = gtServerStatus;
25 | Session["userID"] = userID;
26 | return geetest.getResponseStr();
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/demo/index.aspx.designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | // <自动生成>
3 | // 此代码由工具生成。
4 | //
5 | // 对此文件的更改可能导致不正确的行为,如果
6 | // 重新生成代码,则所做更改将丢失。
7 | // 自动生成>
8 | //------------------------------------------------------------------------------
9 |
10 | namespace demo {
11 |
12 |
13 | public partial class Validate {
14 |
15 | ///
16 | /// form1 控件。
17 | ///
18 | ///
19 | /// 自动生成的字段。
20 | /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
21 | ///
22 | protected global::System.Web.UI.HtmlControls.HtmlForm form1;
23 |
24 | ///
25 | /// submitBtn 控件。
26 | ///
27 | ///
28 | /// 自动生成的字段。
29 | /// 若要进行修改,请将字段声明从设计器文件移到代码隐藏文件。
30 | ///
31 | protected global::System.Web.UI.WebControls.Button submitBtn;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/demo/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的常规信息通过下列特性集
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("demo")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("demo")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 会使此程序集中的类型
18 | // 对 COM 组件不可见。如果需要
19 | // 从 COM 访问此程序集中的某个类型,请针对该类型将 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID
23 | [assembly: Guid("2ed3fb0f-d925-494f-8799-1a9437e7900a")]
24 |
25 | // 程序集的版本信息由下列四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 内部版本号
30 | // 修订版本
31 | //
32 | // 可以指定所有值,也可以使用“修订号”和“内部版本号”的默认值,
33 | // 方法是按如下所示使用 "*":
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/demo/Web.Debug.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
30 |
31 |
--------------------------------------------------------------------------------
/src/GeetestSDK/GeetestSDK/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的常规信息通过以下
6 | // 特性集控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("GeetestSDK")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("GeetestSDK")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 使此程序集中的类型
18 | // 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
19 | // 则将该类型上的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("3dae4dd5-d1cb-45e9-805c-ef42375aea29")]
24 |
25 | // 程序集的版本信息由下面四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
33 | // 方法是按如下所示使用“*”:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("3.1.*")]
36 | [assembly: AssemblyFileVersion("3.1.0.0")]
37 |
--------------------------------------------------------------------------------
/demo/Web.Release.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
19 |
31 |
32 |
--------------------------------------------------------------------------------
/demo/index.aspx.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 | using System.Web.UI;
6 | using System.Web.UI.WebControls;
7 | using GeetestSDK;
8 |
9 | namespace demo
10 | {
11 | public partial class Validate : System.Web.UI.Page
12 | {
13 | protected void Page_Load(object sender, EventArgs e)
14 | {
15 | }
16 | protected void submitBtn_Click(object sender, EventArgs e)
17 | {
18 | GeetestLib geetest = new GeetestLib(GeetestConfig.publicKey, GeetestConfig.privateKey);
19 | Byte gt_server_status_code = (Byte) Session[GeetestLib.gtServerStatusSessionKey];
20 | String userID = (String) Session["userID"];
21 | int result = 0;
22 | String challenge = Request.Form.Get(GeetestLib.fnGeetestChallenge);
23 | String validate = Request.Form.Get(GeetestLib.fnGeetestValidate);
24 | String seccode = Request.Form.Get(GeetestLib.fnGeetestSeccode);
25 | if (gt_server_status_code == 1) result = geetest.enhencedValidateRequest(challenge, validate, seccode, userID);
26 | else result = geetest.failbackValidateRequest(challenge, validate, seccode);
27 | if (result == 1) Response.Write("success");
28 | else Response.Write("fail");
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/GeetestSDK/GeetestSDK.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.21005.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GeetestSDK", "GeetestSDK\GeetestSDK.csproj", "{CC55EA94-B545-404C-B5BF-0AD5358DFCB5}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "demo", "..\..\demo\demo.csproj", "{E396F2E0-9781-4E47-9DD8-826EAC1920EA}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {CC55EA94-B545-404C-B5BF-0AD5358DFCB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {CC55EA94-B545-404C-B5BF-0AD5358DFCB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {CC55EA94-B545-404C-B5BF-0AD5358DFCB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {CC55EA94-B545-404C-B5BF-0AD5358DFCB5}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {E396F2E0-9781-4E47-9DD8-826EAC1920EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {E396F2E0-9781-4E47-9DD8-826EAC1920EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {E396F2E0-9781-4E47-9DD8-826EAC1920EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {E396F2E0-9781-4E47-9DD8-826EAC1920EA}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | Gt C# SDK
2 | =========
3 |
4 | 极验验证 C# SDK,支持.Net Framework3.5及以上版本.本项目提供的Demo的前端实现方法均是面向PC端的。 本项目是面向服务器端的,具体使用可以参考我们的 `文档 `_ ,客户端相关开发请参考我们的 `前端文档 `_.
5 |
6 | 开发环境
7 | ________
8 |
9 | - Visual Studio(推荐VS2012以上版本)
10 | - .NET Framework 4.5
11 |
12 | 快速开始
13 | ________
14 |
15 | 1. 从 `Github `_ 上Clone代码:
16 |
17 | .. code-block:: bash
18 |
19 | $ git clone https://github.com/GeeTeam/gt-csharp-sdk.git
20 |
21 | 2. 根据你的.Net Framework版本编译代码(或者用VS打开项目直接运行DEMO).
22 | #. 将编译完成的DLL引入你的项目.
23 | #. 编写你的代码,代码示例:
24 |
25 | .. code-block:: csharp
26 |
27 | using System;
28 | using System.Collections.Generic;
29 | using System.Linq;
30 | using System.Web;
31 | using System.Web.UI;
32 | using System.Web.UI.WebControls;
33 | using GeetestSDK;
34 |
35 | namespace demo
36 | {
37 | public partial class GetCaptcha : System.Web.UI.Page
38 | {
39 | protected void Page_Load(object sender, EventArgs e)
40 | {
41 | Response.ContentType = "application/json";
42 | Response.Write(getCaptcha());
43 | Response.End();
44 | }
45 | private String getCaptcha()
46 | {
47 | GeetestLib geetest = new GeetestLib(GeetestConfig.publicKey, GeetestConfig.privateKey);
48 | Byte gtServerStatus = geetest.preProcess();
49 | Session[GeetestLib.gtServerStatusSessionKey] = gtServerStatus;
50 | return geetest.getResponseStr();
51 | }
52 | }
53 | }
54 |
55 |
56 | 发布日志
57 | -----------------
58 | + 3.1.1
59 |
60 | - 统一接口
61 |
62 | + 3.1.0
63 |
64 | - 添加challenge加密特性,使验证更安全, 老版本更新请先联系管理员
65 |
66 | + 2.0.2
67 | - 修复Failback Bug
68 |
69 | + 2.0.1
70 | - 完善注释
71 | - 添加API文档
72 | - 修改Demo
73 | + 2.0.0
74 | - 去除旧的接口
75 | - 添加注释
76 |
--------------------------------------------------------------------------------
/demo/index.aspx:
--------------------------------------------------------------------------------
1 | <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="index.aspx.cs" Inherits="demo.Validate" %>
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
54 |
55 |
--------------------------------------------------------------------------------
/src/GeetestSDK/GeetestSDK/GeetestSDK.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {CC55EA94-B545-404C-B5BF-0AD5358DFCB5}
8 | Library
9 | Properties
10 | GeetestSDK
11 | GeetestSDK
12 | v4.5
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 | false
25 | GeetestSDK.XML
26 |
27 |
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 | false
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 |
11 | [Dd]ebug/
12 | [Rr]elease/
13 | x64/
14 | build/
15 | [Bb]in/
16 | [Oo]bj/
17 |
18 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
19 | !packages/*/build/
20 |
21 | # MSTest test Results
22 | [Tt]est[Rr]esult*/
23 | [Bb]uild[Ll]og.*
24 |
25 | *_i.c
26 | *_p.c
27 | *.ilk
28 | *.meta
29 | *.obj
30 | *.pch
31 | *.pdb
32 | *.pgc
33 | *.pgd
34 | *.rsp
35 | *.sbr
36 | *.tlb
37 | *.tli
38 | *.tlh
39 | *.tmp
40 | *.tmp_proj
41 | *.log
42 | *.vspscc
43 | *.vssscc
44 | .builds
45 | *.pidb
46 | *.log
47 | *.scc
48 |
49 | # Visual C++ cache files
50 | ipch/
51 | *.aps
52 | *.ncb
53 | *.opensdf
54 | *.sdf
55 | *.cachefile
56 |
57 | # Visual Studio profiler
58 | *.psess
59 | *.vsp
60 | *.vspx
61 |
62 | # Guidance Automation Toolkit
63 | *.gpState
64 |
65 | # ReSharper is a .NET coding add-in
66 | _ReSharper*/
67 | *.[Rr]e[Ss]harper
68 |
69 | # TeamCity is a build add-in
70 | _TeamCity*
71 |
72 | # DotCover is a Code Coverage Tool
73 | *.dotCover
74 |
75 | # NCrunch
76 | *.ncrunch*
77 | .*crunch*.local.xml
78 |
79 | # Installshield output folder
80 | [Ee]xpress/
81 |
82 | # DocProject is a documentation generator add-in
83 | DocProject/buildhelp/
84 | DocProject/Help/*.HxT
85 | DocProject/Help/*.HxC
86 | DocProject/Help/*.hhc
87 | DocProject/Help/*.hhk
88 | DocProject/Help/*.hhp
89 | DocProject/Help/Html2
90 | DocProject/Help/html
91 |
92 | # Click-Once directory
93 | publish/
94 |
95 | # Publish Web Output
96 | *.Publish.xml
97 |
98 | # NuGet Packages Directory
99 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
100 | #packages/
101 |
102 | # Windows Azure Build Output
103 | csx
104 | *.build.csdef
105 |
106 | # Windows Store app package directory
107 | AppPackages/
108 |
109 | # Others
110 | sql/
111 | *.Cache
112 | ClientBin/
113 | [Ss]tyle[Cc]op.*
114 | ~$*
115 | *~
116 | *.dbmdl
117 | *.[Pp]ublish.xml
118 | *.pfx
119 | *.publishsettings
120 |
121 | # RIA/Silverlight projects
122 | Generated_Code/
123 |
124 | # Backup & report files from converting an old project file to a newer
125 | # Visual Studio version. Backup files are not needed, because we have git ;-)
126 | _UpgradeReport_Files/
127 | Backup*/
128 | UpgradeLog*.XML
129 | UpgradeLog*.htm
130 |
131 | # SQL Server files
132 | App_Data/*.mdf
133 | App_Data/*.ldf
134 |
135 |
136 | #LightSwitch generated files
137 | GeneratedArtifacts/
138 | _Pvt_Extensions/
139 | ModelManifest.xml
140 |
141 | # =========================
142 | # Windows detritus
143 | # =========================
144 |
145 | # Windows image file caches
146 | Thumbs.db
147 | ehthumbs.db
148 |
149 | # Folder config file
150 | Desktop.ini
151 |
152 | # Recycle Bin used on file shares
153 | $RECYCLE.BIN/
154 |
155 | # Mac desktop service store files
156 | .DS_Store
157 |
--------------------------------------------------------------------------------
/demo/demo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 |
8 |
9 | 2.0
10 | {E396F2E0-9781-4E47-9DD8-826EAC1920EA}
11 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
12 | Library
13 | Properties
14 | demo
15 | demo
16 | v4.5
17 | true
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | true
26 | full
27 | false
28 | bin\
29 | DEBUG;TRACE
30 | prompt
31 | 4
32 |
33 |
34 | pdbonly
35 | true
36 | bin\
37 | TRACE
38 | prompt
39 | 4
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | Web.config
63 |
64 |
65 | Web.config
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | getcaptcha.aspx
76 | ASPXCodeBehind
77 |
78 |
79 | getcaptcha.aspx
80 |
81 |
82 | index.aspx
83 | ASPXCodeBehind
84 |
85 |
86 | index.aspx
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | {cc55ea94-b545-404c-b5bf-0ad5358dfcb5}
97 | GeetestSDK
98 |
99 |
100 |
101 | 10.0
102 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | True
112 | True
113 | 2434
114 | /
115 | http://localhost:2434/
116 | False
117 | False
118 |
119 |
120 | False
121 |
122 |
123 |
124 |
125 |
132 |
--------------------------------------------------------------------------------
/src/GeetestSDK/GeetestSDK/GeetestLib.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Security.Cryptography;
7 | using System.Net;
8 | using System.IO;
9 |
10 | namespace GeetestSDK
11 | {
12 | ///
13 | /// GeetestLib 极验验证C# SDK基本库
14 | ///
15 | public class GeetestLib
16 | {
17 | ///
18 | /// SDK版本号
19 | ///
20 | public const String version = "3.2.0";
21 | ///
22 | /// SDK开发语言
23 | ///
24 | public const String sdkLang = "csharp";
25 | ///
26 | /// 极验验证API URL
27 | ///
28 | protected const String apiUrl = "http://api.geetest.com";
29 | ///
30 | /// register url
31 | ///
32 | protected const String registerUrl = "/register.php";
33 | ///
34 | /// validate url
35 | ///
36 | protected const String validateUrl = "/validate.php";
37 | ///
38 | /// 极验验证API服务状态Session Key
39 | ///
40 | public const String gtServerStatusSessionKey = "gt_server_status";
41 | ///
42 | /// 极验验证二次验证表单数据 Chllenge
43 | ///
44 | public const String fnGeetestChallenge = "geetest_challenge";
45 | ///
46 | /// 极验验证二次验证表单数据 Validate
47 | ///
48 | public const String fnGeetestValidate = "geetest_validate";
49 | ///
50 | /// 极验验证二次验证表单数据 Seccode
51 | ///
52 | public const String fnGeetestSeccode = "geetest_seccode";
53 | private String userID = "";
54 | private String responseStr = "";
55 | private String captchaID = "";
56 | private String privateKey = "";
57 |
58 | ///
59 | /// 验证成功结果字符串
60 | ///
61 | public const int successResult = 1;
62 | ///
63 | /// 证结失败验果字符串
64 | ///
65 | public const int failResult = 0;
66 | ///
67 | /// 判定为机器人结果字符串
68 | ///
69 | public const String forbiddenResult = "forbidden";
70 |
71 | ///
72 | /// GeetestLib构造函数
73 | ///
74 | /// 极验验证公钥
75 | /// 极验验证私钥
76 | public GeetestLib(String publicKey, String privateKey)
77 | {
78 | this.privateKey = privateKey;
79 | this.captchaID = publicKey;
80 | }
81 | private int getRandomNum()
82 | {
83 | Random rand =new Random();
84 | int randRes = rand.Next(100);
85 | return randRes;
86 | }
87 |
88 | ///
89 | /// 验证初始化预处理
90 | ///
91 | /// 初始化结果
92 | public Byte preProcess()
93 | {
94 | if (this.captchaID == null)
95 | {
96 | Console.WriteLine("publicKey is null!");
97 | }
98 | else
99 | {
100 | String challenge = this.registerChallenge();
101 | if (challenge.Length == 32)
102 | {
103 | this.getSuccessPreProcessRes(challenge);
104 | return 1;
105 | }
106 | else
107 | {
108 | this.getFailPreProcessRes();
109 | Console.WriteLine("Server regist challenge failed!");
110 | }
111 | }
112 |
113 | return 0;
114 |
115 | }
116 | public Byte preProcess(String userID)
117 | {
118 | if (this.captchaID == null)
119 | {
120 | Console.WriteLine("publicKey is null!");
121 | }
122 | else
123 | {
124 | this.userID = userID;
125 | String challenge = this.registerChallenge();
126 | if (challenge.Length == 32)
127 | {
128 | this.getSuccessPreProcessRes(challenge);
129 | return 1;
130 | }
131 | else
132 | {
133 | this.getFailPreProcessRes();
134 | Console.WriteLine("Server regist challenge failed!");
135 | }
136 | }
137 |
138 | return 0;
139 |
140 | }
141 | public String getResponseStr()
142 | {
143 | return this.responseStr;
144 | }
145 | ///
146 | /// 预处理失败后的返回格式串
147 | ///
148 | private void getFailPreProcessRes()
149 | {
150 | int rand1 = this.getRandomNum();
151 | int rand2 = this.getRandomNum();
152 | String md5Str1 = this.md5Encode(rand1 + "");
153 | String md5Str2 = this.md5Encode(rand2 + "");
154 | String challenge = md5Str1 + md5Str2.Substring(0, 2);
155 | this.responseStr = "{" + string.Format(
156 | "\"success\":{0},\"gt\":\"{1}\",\"challenge\":\"{2}\"", 0,
157 | this.captchaID, challenge) + "}";
158 | }
159 | ///
160 | /// 预处理成功后的标准串
161 | ///
162 | private void getSuccessPreProcessRes(String challenge)
163 | {
164 | challenge = this.md5Encode(challenge + this.privateKey);
165 | this.responseStr ="{" + string.Format(
166 | "\"success\":{0},\"gt\":\"{1}\",\"challenge\":\"{2}\"", 1,
167 | this.captchaID, challenge) + "}";
168 | }
169 | ///
170 | /// failback模式的验证方式
171 | ///
172 | /// failback模式下用于与validate一起解码答案, 判断验证是否正确
173 | /// failback模式下用于与challenge一起解码答案, 判断验证是否正确
174 | /// failback模式下,其实是个没用的参数
175 | /// 验证结果
176 | public int failbackValidateRequest(String challenge, String validate, String seccode)
177 | {
178 | if (!this.requestIsLegal(challenge, validate, seccode)) return GeetestLib.failResult;
179 | String[] validateStr = validate.Split('_');
180 | String encodeAns = validateStr[0];
181 | String encodeFullBgImgIndex = validateStr[1];
182 | String encodeImgGrpIndex = validateStr[2];
183 | int decodeAns = this.decodeResponse(challenge, encodeAns);
184 | int decodeFullBgImgIndex = this.decodeResponse(challenge, encodeFullBgImgIndex);
185 | int decodeImgGrpIndex = this.decodeResponse(challenge, encodeImgGrpIndex);
186 | int validateResult = this.validateFailImage(decodeAns, decodeFullBgImgIndex, decodeImgGrpIndex);
187 | return validateResult;
188 | }
189 | private int validateFailImage(int ans, int full_bg_index, int img_grp_index)
190 | {
191 | const int thread = 3;
192 | String full_bg_name = this.md5Encode(full_bg_index + "").Substring(0, 10);
193 | String bg_name = md5Encode(img_grp_index + "").Substring(10, 10);
194 | String answer_decode = "";
195 | for (int i = 0;i < 9; i++)
196 | {
197 | if (i % 2 == 0) answer_decode += full_bg_name.ElementAt(i);
198 | else if (i % 2 == 1) answer_decode += bg_name.ElementAt(i);
199 | }
200 | String x_decode = answer_decode.Substring(4);
201 | int x_int = Convert.ToInt32(x_decode, 16);
202 | int result = x_int % 200;
203 | if (result < 40) result = 40;
204 | if (Math.Abs(ans - result) < thread) return GeetestLib.successResult;
205 | else return GeetestLib.failResult;
206 | }
207 | private Boolean requestIsLegal(String challenge, String validate, String seccode)
208 | {
209 | if (challenge.Equals(string.Empty) || validate.Equals(string.Empty) || seccode.Equals(string.Empty)) return false;
210 | return true;
211 | }
212 |
213 | ///
214 | /// 向gt-server进行二次验证
215 | ///
216 | /// 本次验证会话的唯一标识
217 | /// 拖动完成后server端返回的验证结果标识字符串
218 | /// 验证结果的校验码,如果gt-server返回的不与这个值相等则表明验证失败
219 | /// 二次验证结果
220 | public int enhencedValidateRequest(String challenge, String validate, String seccode)
221 | {
222 | if (!this.requestIsLegal(challenge, validate, seccode)) return GeetestLib.failResult;
223 | if (validate.Length > 0 && checkResultByPrivate(challenge, validate))
224 | {
225 | String query = "seccode=" + seccode + "&sdk=csharp_" + GeetestLib.version;
226 | String response = "";
227 | try
228 | {
229 | response = postValidate(query);
230 | }
231 | catch (Exception e)
232 | {
233 | Console.WriteLine(e);
234 | }
235 | if (response.Equals(md5Encode(seccode)))
236 | {
237 | return GeetestLib.successResult;
238 | }
239 | }
240 | return GeetestLib.failResult;
241 | }
242 | public int enhencedValidateRequest(String challenge, String validate, String seccode, String userID)
243 | {
244 | if (!this.requestIsLegal(challenge, validate, seccode)) return GeetestLib.failResult;
245 | if (validate.Length > 0 && checkResultByPrivate(challenge, validate))
246 | {
247 | String query = "seccode=" + seccode + "&user_id=" + userID + "&sdk=csharp_" + GeetestLib.version;
248 | String response = "";
249 | try
250 | {
251 | response = postValidate(query);
252 | }
253 | catch (Exception e)
254 | {
255 | Console.WriteLine(e);
256 | }
257 | if (response.Equals(md5Encode(seccode)))
258 | {
259 | return GeetestLib.successResult;
260 | }
261 | }
262 | return GeetestLib.failResult;
263 | }
264 | private String readContentFromGet(String url)
265 | {
266 | try
267 | {
268 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
269 | request.Timeout = 20000;
270 | HttpWebResponse response = (HttpWebResponse)request.GetResponse();
271 | Stream myResponseStream = response.GetResponseStream();
272 | StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
273 | String retString = myStreamReader.ReadToEnd();
274 | myStreamReader.Close();
275 | myResponseStream.Close();
276 | return retString;
277 | }
278 | catch
279 | {
280 | return "";
281 | }
282 |
283 | }
284 | private String registerChallenge()
285 | {
286 | String url = "";
287 | if (string.Empty.Equals(this.userID))
288 | {
289 | url = string.Format("{0}{1}?gt={2}", GeetestLib.apiUrl, GeetestLib.registerUrl, this.captchaID);
290 | }
291 | else
292 | {
293 | url = string.Format("{0}{1}?gt={2}&user_id={3}", GeetestLib.apiUrl, GeetestLib.registerUrl, this.captchaID, this.userID);
294 | }
295 | string retString = this.readContentFromGet(url);
296 | return retString;
297 | }
298 | private Boolean checkResultByPrivate(String origin, String validate)
299 | {
300 | String encodeStr = md5Encode(privateKey + "geetest" + origin);
301 | return validate.Equals(encodeStr);
302 | }
303 | private String postValidate(String data)
304 | {
305 | String url = string.Format("{0}{1}", GeetestLib.apiUrl, GeetestLib.validateUrl);
306 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
307 | request.Method = "POST";
308 | request.ContentType = "application/x-www-form-urlencoded";
309 | request.ContentLength = Encoding.UTF8.GetByteCount(data);
310 | // 发送数据
311 | Stream myRequestStream = request.GetRequestStream();
312 | byte[] requestBytes = System.Text.Encoding.ASCII.GetBytes(data);
313 | myRequestStream.Write(requestBytes, 0, requestBytes.Length);
314 | myRequestStream.Close();
315 |
316 | HttpWebResponse response = (HttpWebResponse)request.GetResponse();
317 | // 读取返回信息
318 | Stream myResponseStream = response.GetResponseStream();
319 | StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
320 | string retString = myStreamReader.ReadToEnd();
321 | myStreamReader.Close();
322 | myResponseStream.Close();
323 |
324 | return retString;
325 |
326 | }
327 | private int decodeRandBase(String challenge)
328 | {
329 | String baseStr = challenge.Substring(32, 2);
330 | List tempList = new List();
331 | for(int i = 0; i < baseStr.Length; i++)
332 | {
333 | int tempAscii = (int)baseStr[i];
334 | tempList.Add((tempAscii > 57) ? (tempAscii - 87)
335 | : (tempAscii - 48));
336 | }
337 | int result = tempList.ElementAt(0) * 36 + tempList.ElementAt(1);
338 | return result;
339 | }
340 | private int decodeResponse(String challenge, String str)
341 | {
342 | if (str.Length>100) return 0;
343 | int[] shuzi = new int[] { 1, 2, 5, 10, 50};
344 | String chongfu = "";
345 | Hashtable key = new Hashtable();
346 | int count = 0;
347 | for (int i=0;i