首页>代码>jsp滑动拼图极验验证java代码,让用户登录注册更安全,使页面效果更精美>/极验验证/gt-java-sdk-demo/src/com/geetest/sdk/java/GeetestLib.java
package com.geetest.sdk.java;

import java.awt.print.Printable;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Logger;

import javax.print.DocFlavor.STRING;
import javax.servlet.http.HttpServletRequest;

/**
 * Java SDK
 * 
 */
public class GeetestLib {

	protected final String verName = "3.3.0";// SDK版本编号
	protected final String sdkLang = "java";// SD的语言类型

	protected final String apiUrl = "http://api.geetest.com"; //极验验证API URL
	protected final String baseUrl = "api.geetest.com";
	
	protected final String registerUrl = "/register.php"; //register url
	protected final String validateUrl = "/validate.php"; //validate url

	/**
	 * 极验验证二次验证表单数据 chllenge
	 */
	public static final String fn_geetest_challenge = "geetest_challenge";
	
	/**
	 * 极验验证二次验证表单数据 validate
	 */
	public static final String fn_geetest_validate = "geetest_validate";
	
	/**
	 * 极验验证二次验证表单数据 seccode
	 */
	public static final String fn_geetest_seccode = "geetest_seccode";

	/**
	 * 公钥
	 */
	private String captchaId = "";

	/**
	 * 私钥
	 */
	
	private String privateKey = "";
	
	private String userId = "";

	private String responseStr = "";
	
	/**
	 * 调试开关,是否输出调试日志
	 */
	public boolean debugCode = true;
	
	/**
	 * 极验验证API服务状态Session Key
	 */
	public String gtServerStatusSessionKey = "gt_server_status";
	
	/**
	 * 带参数构造函数
	 * 
	 * @param captchaId
	 * @param privateKey
	 */
	public GeetestLib(String captchaId, String privateKey) {
		this.captchaId = captchaId;
		this.privateKey = privateKey;
	}
	
	/**
	 * 获取本次验证初始化返回字符串
	 * 
	 * @return 初始化结果
	 */
	public String getResponseStr() {
		return responseStr;
	}
	
	public String getVersionInfo() {
		return verName;
	}

	/**
	 * 预处理失败后的返回格式串
	 * 
	 * @return
	 */
	private String getFailPreProcessRes() {

		Long rnd1 = Math.round(Math.random() * 100);
		Long rnd2 = Math.round(Math.random() * 100);
		String md5Str1 = md5Encode(rnd1 + "");
		String md5Str2 = md5Encode(rnd2 + "");
		String challenge = md5Str1 + md5Str2.substring(0, 2);

		return String.format(
				"{\"success\":%s,\"gt\":\"%s\",\"challenge\":\"%s\"}", 0,
				this.captchaId, challenge);
	}

	/**
	 * 预处理成功后的标准串
	 * 
	 */
	private String getSuccessPreProcessRes(String challenge) {
		
		gtlog("challenge:" + challenge);
		return String.format(
				"{\"success\":%s,\"gt\":\"%s\",\"challenge\":\"%s\"}", 1,
				this.captchaId, challenge);
	}

	/**
	 * 验证初始化预处理
	 *
	 * @return 1表示初始化成功,0表示初始化失败
	 */
	public int preProcess() {

		if (registerChallenge() != 1) {
			
			this.responseStr = this.getFailPreProcessRes();
			return 0;
		}
		
		return 1;

	}
	
	/**
	 * 验证初始化预处理
	 *
	 * @param userid
	 * @return 1表示初始化成功,0表示初始化失败
	 */
	public int preProcess(String userid){
		
		this.userId = userid;
		return this.preProcess();
	}
	
	

	/**
	 * 用captchaID进行注册,更新challenge
	 * 
	 * @return 1表示注册成功,0表示注册失败
	 */
	private int registerChallenge() {
		try {
			String GET_URL = apiUrl + registerUrl+"?gt=" + this.captchaId;
			if (this.userId != ""){
				GET_URL = GET_URL + "&user_id=" + this.userId;
				this.userId = "";
			}
			gtlog("GET_URL:" + GET_URL);
			String result_str = readContentFromGet(GET_URL);
			gtlog("register_result:" + result_str);
			if (32 == result_str.length()) {

				this.responseStr = this.getSuccessPreProcessRes(this.md5Encode(result_str + this.privateKey));
				
				return 1;
			} else {
				gtlog("gtServer register challenge failed");
				return 0;
			}
		} catch (Exception e) {
			gtlog("exception:register api");
		}
		return 0;
	}

	/**
	 * 发送请求,获取服务器返回结果
	 * 
	 * @param getURL
	 * @return 服务器返回结果
	 * @throws IOException
	 */
	private String readContentFromGet(String getURL) throws IOException {

		URL getUrl = new URL(getURL);
		HttpURLConnection connection = (HttpURLConnection) getUrl
				.openConnection();

		connection.setConnectTimeout(2000);// 设置连接主机超时(单位:毫秒)
		connection.setReadTimeout(2000);// 设置从主机读取数据超时(单位:毫秒)

		// 建立与服务器的连接,并未发送数据
		connection.connect();
		
		// 发送数据到服务器并使用Reader读取返回的数据
		StringBuffer sBuffer = new StringBuffer();

		InputStream inStream = null;
		byte[] buf = new byte[1024];
		inStream = connection.getInputStream();
		for (int n; (n = inStream.read(buf)) != -1;) {
			sBuffer.append(new String(buf, 0, n, "UTF-8"));
		}
		inStream.close();
		connection.disconnect();// 断开连接

		return sBuffer.toString();
	}
	
	
	
	
	/**
	 * 判断一个表单对象值是否为空
	 * 
	 * @param gtObj
	 * @return
	 */
	protected boolean objIsEmpty(Object gtObj) {
		if (gtObj == null) {
			return true;
		}

		if (gtObj.toString().trim().length() == 0) {
			return true;
		}

		return false;
	}

	/**
	 * 检查客户端的请求是否合法,三个只要有一个为空,则判断不合法
	 * 
	 * @param request
	 * @return
	 */
	private boolean resquestIsLegal(String challenge, String validate, String seccode) {

		if (objIsEmpty(challenge)) {
			return false;
		}

		if (objIsEmpty(validate)) {
			return false;
		}

		if (objIsEmpty(seccode)) {
			return false;
		}

		return true;
	}
	
	
	/**
	 * 服务正常的情况下使用的验证方式,向gt-server进行二次验证,获取验证结果
	 * 
	 * @param challenge
	 * @param validate
	 * @param seccode
	 * @return 验证结果,1表示验证成功0表示验证失败
	 */
	public int enhencedValidateRequest(String challenge, String validate, String seccode) {	
		
		if (!resquestIsLegal(challenge, validate, seccode)) {
			return 0;
		}
		gtlog("request legitimate");
		
		String host = baseUrl;
		String path = validateUrl;
		int port = 80;
		String query = String.format("seccode=%s&sdk=%s", seccode,
				(this.sdkLang + "_" + this.verName));
		String response = "";
		
		if (this.userId != ""){
			query = query + "&user_id=" + this.userId;
			this.userId = "";
		}
		gtlog(query);
		try {
			if (validate.length() <= 0) {
				return 0;
			}

			if (!checkResultByPrivate(challenge, validate)) {
				return 0;
			}
			gtlog("checkResultByPrivate");
			response = postValidate(host, path, query, port);

			gtlog("response: " + response);
		} catch (Exception e) {
			e.printStackTrace();
		}

		gtlog("md5: " + md5Encode(seccode));

		if (response.equals(md5Encode(seccode))) {
			return 1;
		} else {
			return 0;
		}
	}
	
	/**
	 * 服务正常的情况下使用的验证方式,向gt-server进行二次验证,获取验证结果
	 * 
	 * @param challenge
	 * @param validate
	 * @param seccode
	 * @param userid
	 * @return 验证结果,1表示验证成功0表示验证失败
	 */
	public int enhencedValidateRequest(String challenge, String validate, String seccode, String userid) {	
		
		this.userId = userid;
		return this.enhencedValidateRequest(challenge, validate, seccode);
	}

	/**
	 * failback使用的验证方式
	 * 
	 * @param challenge
	 * @param validate
	 * @param seccode
	 * @return 验证结果,1表示验证成功0表示验证失败
	 */
	public int failbackValidateRequest(String challenge, String validate, String seccode) {

		gtlog("in failback validate");

		if (!resquestIsLegal(challenge, validate, seccode)) {
			return 0;
		}
		gtlog("request legitimate");

		String[] validateStr = validate.split("_");
		String encodeAns = validateStr[0];
		String encodeFullBgImgIndex = validateStr[1];
		String encodeImgGrpIndex = validateStr[2];

		gtlog(String.format(
				"encode----challenge:%s--ans:%s,bg_idx:%s,grp_idx:%s",
				challenge, encodeAns, encodeFullBgImgIndex, encodeImgGrpIndex));
			
		int decodeAns = decodeResponse(challenge, encodeAns);
		int decodeFullBgImgIndex = decodeResponse(challenge, encodeFullBgImgIndex);
		int decodeImgGrpIndex = decodeResponse(challenge, encodeImgGrpIndex);

		gtlog(String.format("decode----ans:%s,bg_idx:%s,grp_idx:%s", decodeAns,
				decodeFullBgImgIndex, decodeImgGrpIndex));

		int validateResult = validateFailImage(decodeAns,decodeFullBgImgIndex, decodeImgGrpIndex);

		return validateResult;
	}
	
	

	/**
	 *
	 * @param ans
	 * @param full_bg_index
	 * @param img_grp_index
	 * @return
	 */
	private int validateFailImage(int ans, int full_bg_index,
			int img_grp_index) {
		final int thread = 3;// 容差值

		String full_bg_name = md5Encode(full_bg_index + "").substring(0, 9);
		String bg_name = md5Encode(img_grp_index + "").substring(10, 19);

		String answer_decode = "";

		// 通过两个字符串奇数和偶数位拼接产生答案位
		for (int i = 0; i < 9; i++) {
			if (i % 2 == 0) {
				answer_decode += full_bg_name.charAt(i);
			} else if (i % 2 == 1) {
				answer_decode += bg_name.charAt(i);
			} else {
				gtlog("exception");
			}
		}

		String x_decode = answer_decode.substring(4, answer_decode.length());

		int x_int = Integer.valueOf(x_decode, 16);// 16 to 10

		int result = x_int % 200;
		if (result < 40) {
			result = 40;
		}

		if (Math.abs(ans - result) <= thread) {
			return 1;
		} else {
			return 0;
		}
	}
	
	
	
	
	/**
	 * 解码随机参数
	 * 
	 * @param encodeStr
	 * @param challenge
	 * @return
	 */
	private int decodeResponse(String challenge, String string) {
		if (string.length() > 100) {
			return 0;
		}

		int[] shuzi = new int[] { 1, 2, 5, 10, 50 };
		String chongfu = "";
		HashMap<String, Integer> key = new HashMap<String, Integer>();
		int count = 0;

		for (int i = 0; i < challenge.length(); i++) {
			String item = challenge.charAt(i) + "";

			if (chongfu.contains(item) == true) {
				continue;
			} else {
				int value = shuzi[count % 5];
				chongfu += item;
				count++;
				key.put(item, value);
			}
		}

		int res = 0;

		for (int j = 0; j < string.length(); j++) {
			res += key.get(string.charAt(j) + "");
		}

		res = res - decodeRandBase(challenge);

		return res;

	}

	/**
	 * 输入的两位的随机数字,解码出偏移量
	 * 
	 * @param randStr
	 * @return
	 */
	private int decodeRandBase(String challenge) {

		String base = challenge.substring(32, 34);
		ArrayList<Integer> tempArray = new ArrayList<Integer>();

		for (int i = 0; i < base.length(); i++) {
			char tempChar = base.charAt(i);
			Integer tempAscii = (int) (tempChar);

			Integer result = (tempAscii > 57) ? (tempAscii - 87)
					: (tempAscii - 48);

			tempArray.add(result);
		}

		int decodeRes = tempArray.get(0) * 36 + tempArray.get(1);
		return decodeRes;

	}
	
	

	/**
	 * 输出debug信息,需要开启debugCode
	 * 
	 * @param message
	 */
	public void gtlog(String message) {
		if (debugCode) {
			System.out.println("gtlog: " + message);
		}
	}

	protected boolean checkResultByPrivate(String challenge, String validate) {
		String encodeStr = md5Encode(privateKey + "geetest" + challenge);
		return validate.equals(encodeStr);
	}

	/**
	 * 貌似不是Post方式,后面重构时修改名字
	 * 
	 * @param host
	 * @param path
	 * @param data
	 * @param port
	 * @return
	 * @throws Exception
	 */
	protected String postValidate(String host, String path, String data,
			int port) throws Exception {
		String response = "error";
		
		InetAddress addr = InetAddress.getByName(host);
		Socket socket = new Socket(addr, port);
		BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(
				socket.getOutputStream(), "UTF8"));
		wr.write("POST " + path + " HTTP/1.0\r\n");
		wr.write("Host: " + host + "\r\n");
		wr.write("Content-Type: application/x-www-form-urlencoded\r\n");
		wr.write("Content-Length: " + data.length() + "\r\n");
		wr.write("\r\n"); // 以空行作为分割
		
		// 发送数据
		wr.write(data);
		wr.flush();
		
		// 读取返回信息
		BufferedReader rd = new BufferedReader(new InputStreamReader(
				socket.getInputStream(), "UTF-8"));
		String line;
		while ((line = rd.readLine()) != null) {
			response = line;
		}
		wr.close();
		rd.close();
		socket.close();
		return response;
	}


	/**
	 * md5 加密
	 * 
	 * @time 2014年7月10日 下午3:30:01
	 * @param plainText
	 * @return
	 */
	private String md5Encode(String plainText) {
		String re_md5 = new String();
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(plainText.getBytes());
			byte b[] = md.digest();
			int i;
			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}

			re_md5 = buf.toString();

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return re_md5;
	}

}
最近下载更多
xuhaoa  LV2 2023年11月10日
星予宝藏666  LV6 2023年5月31日
qqwerty  LV3 2022年12月12日
dhvdsgfggfjhfggfyu  LV4 2022年6月1日
1306878374  LV13 2022年2月18日
gus123  LV1 2022年1月17日
不良猫  LV3 2021年12月31日
Start1  LV15 2021年11月3日
nbzhou2013  LV14 2021年10月6日
czr2233  LV9 2021年5月6日
最近浏览更多
3263394665  LV9 3月15日
mayufen 1月4日
暂无贡献等级
ling7314  LV4 2023年12月12日
crrey_wei  LV1 2023年11月27日
Henew168  LV2 2023年11月19日
xuhaoa  LV2 2023年11月10日
5061187  LV2 2023年10月7日
sldlqwerty 2023年9月4日
暂无贡献等级
abandan  LV4 2023年6月11日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友