首页>代码>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日
微信网友_6450287428947968 LV2
2月19日
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日