├── .gitignore ├── README.rst ├── demo ├── GeetestConfig.cs ├── Properties │ └── AssemblyInfo.cs ├── Web.Debug.config ├── Web.Release.config ├── Web.config ├── demo.csproj ├── getcaptcha.aspx ├── getcaptcha.aspx.cs ├── getcaptcha.aspx.designer.cs ├── index.aspx ├── index.aspx.cs └── index.aspx.designer.cs └── src └── GeetestSDK ├── GeetestSDK.sln └── GeetestSDK ├── GeetestLib.cs ├── GeetestSDK.csproj └── Properties └── AssemblyInfo.cs /.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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /demo/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 31 | 32 | -------------------------------------------------------------------------------- /demo/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 |
12 |
13 | 14 |
15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /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/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/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 |
13 |
14 | 16 |
17 |
18 | 20 |
21 | 22 | <%--Start Code--%> 23 |
24 |
25 |
26 | 27 |
28 | 29 | 52 |
53 |
54 | 55 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 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 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------