关于Java对接网络验证+实践小例子,简单易懂

一个简单的网络验证小例子,各位大佬勿喷

        突发奇想,如果一位A友找你拿一份 Working Fruits,但是你不想这位A友把你辛苦劳作、熬夜加点写出的代码分享他或她的另外一位朋友B友,也许并不是很有价值的一个小作业而已,但是就像我一样,多多少少有着私心的幼稚心理。这种想法就像你下载一个收费软件一样,所属权是你,需要授权码或者特定的方式得到你的允许,才能够运行整体代码。当然,不要破环人与人之间的关系或情感,学习为本(说笑了),教程只提供参考。 


目录

一. 预备知识点

二. 常见的网络验证   

三. 微验验证原理

四. 代码实现

五. 缺陷与优化


一. 预备知识点

        我们需要了解MD5和RC4加密原理。MD5是一种常用的哈希算法,它可以将任意长度的数据转换为固定长度的哈希值。通过对比哈希值,我们可以验证数据的完整性和一致性。而RC4是一种流密码算法,它可以根据密钥生成伪随机流,用于对数据进行加密和解密。通过使用MD5和RC4加密算法,我们可以确保在网络传输过程中的数据安全性。

        其次,我们需要了解Java反射。Java反射是一种强大的机制,它允许我们在运行时动态地获取类的信息并操作类的成员。在网络验证中,我们可以利用Java反射机制来动态加载和调用验证相关的类和方法(写好了就包装成一个JAR吧),从而实现灵活的验证逻辑。

        当然,网络验证的实现涉及到更多的知识和技术,比如数据库的构建和管理,有自己的服务器自己管理数据,自主随时管理数据,但是表数据的增删改查操作会产生更多的工作量。这些都是我们在实际开发中需要考虑的问题,需要具备相应的知识储备和技能因此,我们不如简单点,用别人写好的验证系统,直接拿来用不就是了,代码越简单越好对吧

        在实际的网络验证中,我们可以借助已有的对接API来实现本地的验证。这意味着我们可以选择市面上已有的验证服务或库,并通过网络接口进行数据传输和验证。通过使用这些对接API,我们可以简化验证的实现过程,提高开发效率。      

二. 常见的网络验证   

        在网络验证领域中,可以找到一些常见的验证案例,如T3、BS、易游、微验、大纸片等验证系统。这些系统各有特点,其中T3验证系统相对容易被破解,易游验证系统在外观上更加简单,但内部却更为复杂。考虑到教程的讲解需要,我们选择使用微验验证管理系统来进行讲解。

        微验验证管理系统以其独特的特点和功能而备受易语言开发者关注。它提供了一种简单而高效的验证解决方案,适用于各种场景和需求。通过微验验证管理系统,确保验证的安全性和可靠性。

        相比于其他验证系统,微验验证管理系统在设计上更加注重用户体验和易用性。它采用了简化的外观设计,使用户能够快速上手并进行验证操作。同时,微验验证管理系统内部的复杂性也为用户提供了更多的灵活性和定制化选项。

        本教程将重点介绍如何使用微验验证管理系统进行验证操作。通过详细的讲解和示例,本教程将帮助自身了解验证的基本原理和操作步骤。读者可以学习如何配置和管理微验验证系统,以及如何应用验证功能到项目中。

三. 微验验证原理

        先不管加密如何加密,解密如何解密,搞清楚这个验证流程,话不多说,看图。

四. 代码实现

        官方提供的Java对接例子只有不能就地运行、同时客户端不具有安卓特定的imei码,否则验证无法过签名,需要实际开发打包成APP才可使用,因此,我二改了官方提供的代码,可以就地运行。

        微验官方已经写好的rc4加密解密方法,可直接使用

        需要具体看懂吗,不需要,只需要明白每个方法的作用,具体怎么实现的不重要,我还是更喜欢面向对象

        RC4加密算法工具类详解

  1. encryRC4String方法:将给定的字符串数据使用RC4算法进行加密,并返回加密后的十六进制字符串形式。参数包括待加密的数据、密钥和字符集。

  2. encryRC4Byte方法:将给定的字符串数据使用RC4算法进行加密,并返回加密后的字节数组形式。参数包括待加密的数据、密钥和字符集。

  3. decryRC4方法:将给定的十六进制字符串数据使用RC4算法进行解密,并返回解密后的字符串形式。参数包括待解密的数据、密钥和字符集。

  4. initKey方法:根据给定的密钥生成RC4算法所需的初始密钥。返回一个字节数组。

  5. bytesToHex方法:将字节数组转换为十六进制字符串形式。返回转换后的字符串。

  6. hexToByte方法:将十六进制字符串转换为字节数组形式。返回转换后的字节数组。

  7. RC4Base方法:根据给定的输入数据和密钥使用RC4算法进行加密或解密操作。返回加密或解密后的字节数组。

     属性KEK 特定的密钥,不同的密钥产生不同的结果,不可更改

        RC4工具类 

import java.io.UnsupportedEncodingException;public class RC4Util {public static final String KEY = "PZ8KBd4TbE7mjEb";public RC4Util() {}public static String encryRC4String(String data, String key, String chartSet) throws UnsupportedEncodingException {return data != null && key != null ? bytesToHex(encryRC4Byte(data, key, chartSet)) : null;}public static byte[] encryRC4Byte(String data, String key, String chartSet) throws UnsupportedEncodingException {if (data != null && key != null) {byte[] bData;if (chartSet != null && !chartSet.isEmpty()) {bData = data.getBytes(chartSet);return RC4Base(bData, key);} else {bData = data.getBytes();return RC4Base(bData, key);}} else {return null;}}public static String decryRC4(String data, String key, String chartSet) throws UnsupportedEncodingException {return data != null && key != null ? new String(RC4Base(hexToByte(data), key), chartSet) : null;}private static byte[] initKey(String aKey) {byte[] bkey = aKey.getBytes();byte[] state = new byte[256];int index1;for(index1 = 0; index1 < 256; ++index1) {state[index1] = (byte)index1;}index1 = 0;int index2 = 0;if (bkey.length == 0) {return null;} else {for(int i = 0; i < 256; ++i) {index2 = (bkey[index1] & 255) + (state[i] & 255) + index2 & 255;byte tmp = state[i];state[i] = state[index2];state[index2] = tmp;index1 = (index1 + 1) % bkey.length;}return state;}}public static String bytesToHex(byte[] bytes) {StringBuffer sb = new StringBuffer();for(int i = 0; i < bytes.length; ++i) {String hex = Integer.toHexString(bytes[i] & 255);if (hex.length() < 2) {sb.append(0);}sb.append(hex);}return sb.toString();}public static byte[] hexToByte(String inHex) {int hexlen = inHex.length();byte[] result;if (hexlen % 2 == 1) {++hexlen;result = new byte[hexlen / 2];inHex = "0" + inHex;} else {result = new byte[hexlen / 2];}int j = 0;for(int i = 0; i < hexlen; i += 2) {result[j] = (byte)Integer.parseInt(inHex.substring(i, i + 2), 16);++j;}return result;}private static byte[] RC4Base(byte[] input, String mKkey) {int x = 0;int y = 0;byte[] key = initKey(mKkey);byte[] result = new byte[input.length];for(int i = 0; i < input.length; ++i) {x = x + 1 & 255;y = (key[x] & 255) + y & 255;byte tmp = key[x];key[x] = key[y];key[y] = tmp;int xorIndex = (key[x] & 255) + (key[y] & 255) & 255;result[i] = (byte)(input[i] ^ key[xorIndex]);}return result;}
}

        接下来是通过官方提供的加密工具类自主写的对接例子类,可以通过上文中的验证流程图共同参考。

        WeiYan对接类

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.Random;//TODO:Benmaopublic class WeiYan {String kami;//卡密public String markcode;//设备码public long time;//时间戳//Long time = System.currentTimeMillis()public String appKey="57012";//不可更改//"kami="+卡密+"&markcode="+设备码+"&t="+时间戳+"&"+sss.APPKEYpublic String data;public String SIGN;//通过md5加密public int random;//随机数,范围[1000, 9999]public String url="https://wy.llua.cn/api/?id=kmlogon"+"&app="+this.appKey+"&data=";//加密字段MD5public void Gm(String kami){this.kami=kami;this.time=System.currentTimeMillis()/1000;//Long.parseLong(String.valueOf(System.currentTimeMillis()).substring(0 ,10))this.markcode=getDeviceID();//getDeviceID();//需要加密的字段String str="kami="+this.kami+"&markcode="+this.markcode+"&t="+this.time+"&"+this.appKey;this.SIGN = stringToMD5(str);//encodeMD5(str);}//Rce4字段加密public void GD(){//随机数this.random=new Random().nextInt(99999)+1000;//范围1000~9999//需要加密的字段String str="kami="+this.kami+"&markcode="+this.markcode+"&t="+this.time+"&sign="+this.SIGN+"&value"+this.time+this.random;try {this.data=RC4Util.encryRC4String(str, RC4Util.KEY, "UTF-8");url+=this.data;} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}}//返回数据解密public String deRec4(String anUrl){//String anUrl = "https://wy.llua.cn/api/?id=kmlogon&app=57012&data=4a5311e1cf22abb6c079de314f7f7ca9670658e0d306b87a9ab62f560e75ec31cdb0598abc2df00063003484e229ee81d0e07daf64b6d8a4cd190835bdf0c8bbd329b901888296a9a376c9bd73e62f56bce31982e072a38f8fb1fc261d43ce7231edf7c7a883bfec92c47475f0a07e3045161fcc10e5";URL url = null;String res ="";//最终结果try {url = new URL(anUrl);URLConnection conn = url.openConnection();BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));String inputLine;StringBuilder result = new StringBuilder();while ((inputLine = in.readLine()) != null) {result.append(inputLine);}//System.out.println(result);//加密前的字段res=result.toString();} catch (Exception e) {throw new RuntimeException(e);}//解码try {String json = RC4Util.decryRC4(res, RC4Util.KEY, "UTF-8");return json;} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}}//MD5加密public static String encodeMD5(String str){try{MessageDigest md5 = MessageDigest.getInstance("MD5");md5.update(str.getBytes("UTF-8"));byte messageDigest[] = md5.digest();StringBuilder hexString = new StringBuilder();for (byte b : messageDigest){hexString.append(String.format("%02X", b));}return hexString.toString().toLowerCase();}catch (Exception e){e.printStackTrace();}return "";}//iApp Md5加密public static String stringToMD5(String plainText){byte[] secretBytes = new byte[0];try {secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes());} catch (NoSuchAlgorithmException e) {throw new RuntimeException(e);}String md5code = new BigInteger(1, secretBytes).toString(16);for(int i = 0; i < 32 - md5code.length(); i++){md5code = "0" + md5code;}return md5code;}//获取独立设备码public static String getDeviceID() {try {Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();while (networkInterfaces.hasMoreElements()) {NetworkInterface networkInterface = networkInterfaces.nextElement();byte[] mac = networkInterface.getHardwareAddress();if (mac != null) {StringBuilder sb = new StringBuilder();for (byte b : mac) {sb.append(String.format("%02X", b));}return sb.toString().toLowerCase();}}} catch (SocketException e) {e.printStackTrace();}return null;}
}

RC4加密算法工具类详解 

  1. Gm方法:对卡密进行加密处理,生成设备码和时间戳,并计算签名。参数为卡密。

  2. GD方法:对需要加密的字段进行RC4加密,并生成随机数。参数为卡密。

  3. deRec4方法:对返回的数据进行解密处理。参数为需要解密的URL。

  4. encodeMD5方法:对字符串进行MD5加密处理。参数为待加密的字符串。

  5. stringToMD5方法:对字符串进行MD5加密处理,并返回加密后的结果。参数为待加密的字符串。

  6. getDeviceID方法:获取设备的唯一标识码。

  7. kami(卡密)、markcode(设备码)、time(时间戳)、appKey(应用密钥)、data(加密后的数据)、SIGN(签名)、random(随机数)和url(请求的URL)。

    public String getKami() {return kami;}public void setKami(String kami) {this.kami = kami;}public String getMarkcode() {return markcode;}public void setMarkcode(String markcode) {this.markcode = markcode;}public long getTime() {return time;}public void setTime(long time) {this.time = time;}public String getAppKey() {return appKey;}public void setAppKey(String appKey) {this.appKey = appKey;}public String getData() {return data;}public void setData(String data) {this.data = data;}public String getSIGN() {return SIGN;}public void setSIGN(String SIGN) {this.SIGN = SIGN;}public int getRandom() {return random;}public void setRandom(int random) {this.random = random;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}

        接下来就是写一个验证例子。上述代码编译成一个jar包,然后使用反射调用其内部方法

         Main类

/*** @作者:笨猫* @create: 2024-03-16 14:52**/
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;public class main {public static void main(String[] args) {String kami = "Benmao2127FC";//这个就是卡密try {// 反射调用 WeiYan()构造方法,输出this.urlClass<?> weiYanClass = Class.forName("top.benmao.rc4.WeiYan");Constructor<?> weiYanConstructor = weiYanClass.getConstructor();Object weiYanObject = weiYanConstructor.newInstance();Method getUrlMethod = weiYanClass.getDeclaredMethod("getUrl");getUrlMethod.setAccessible(true);String url = (String) getUrlMethod.invoke(weiYanObject);System.out.println("this.url: " + url);// 反射调用Gm方法,并输出属性this.SIGNMethod gmMethod = weiYanClass.getDeclaredMethod("Gm", String.class);gmMethod.setAccessible(true);gmMethod.invoke(weiYanObject, kami);String sign = (String) weiYanClass.getField("SIGN").get(weiYanObject);System.out.println("this.SIGN: " + sign);// 反射调用GD方法,再次输出this.urlMethod gdMethod = weiYanClass.getDeclaredMethod("GD");gdMethod.setAccessible(true);gdMethod.invoke(weiYanObject);url = (String) getUrlMethod.invoke(weiYanObject);System.out.println("this.url: " + url);// 反射调用deRec4()方法,获取返回值并输出Method deRec4Method = weiYanClass.getDeclaredMethod("deRec4", String.class);deRec4Method.setAccessible(true);String result = (String) deRec4Method.invoke(weiYanObject, url);System.out.println("Result: " + result);} catch (Exception e) {e.printStackTrace();}}
}

        运行结果

        只需要把获取的结果JSON后进入校验即可,剩下的就看自己怎么运用吧。

五. 缺陷与优化

        想说的是,比起官方提供的代码,就地运行只需要懂一点点Java语言,有可能解密就只是一个变量的事情,如果需要更加安全、高效、易处理的工作方式,可以继续尝试包装成一个apk并选择各大官方的加固平台进行加固,如360加固。

        本次教程结束了,感兴趣的可以关注我,如有与本博客持有不同的看法或评判,请随时留意吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/763607.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构:详解【栈和队列】的实现

目录 1. 栈1.1 栈的概念及结构1.2 栈的实现1.3 栈的功能1.4 栈的功能的实现1.5 完整代码 2. 队列2.1 队列的概念及结构2.2 队列的实现2.3 队列的功能2.4 队列的功能的实现2.5 完整代码 1. 栈 1.1 栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的…

模拟B\S服务器(扩展知识点)

3.2 模拟B\S服务器(扩展知识点) 模拟网站服务器&#xff0c;使用浏览器访问自己编写的服务端程序&#xff0c;查看网页效果。 案例分析 准备页面数据&#xff0c;web文件夹。 复制到我们Module中&#xff0c;比如复制到day08中 我们模拟服务器端&#xff0c;ServerSocket类…

SpringCloud Alibaba实战和源码(8)OpenFeign使用

1、 使用Feign实现远程HTTP调用 1.1、常见HTTP客户端 HttpClient HttpClient 是 Apache Jakarta Common 下的子项目&#xff0c;用来提供高效的、最新的、功能丰富的支持 Http 协 议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议最新版本和建议。HttpClient 相比传统 J…

RN开发搬砖经验之—处理“Duplicate class com.github.barteksc.pdfviewer“

问题信息 Duplicate class com.github.barteksc.pdfviewer.PDFView found in modules jetified-AndroidPdfViewer-3.1.0-beta.3-runtime (com.github.TalbotGooday:AndroidPdfViewer:3.1.0-beta.3) and jetified-android-pdf-viewer-2.8.2-runtime (com.github.barteksc:andro…

为车主提供多路况安全保障!“北欧轮胎安全专家”熊牌轮胎迎来全新升级

德国马牌轮胎旗下明星品牌——Gislaved熊牌轮胎迎来全新升级。 自进入中国市场以来&#xff0c;熊牌轮胎凭借着坚韧安全、静音降噪等特点&#xff0c;收获无数好评。此次全新升级的熊牌轮胎&#xff0c;在品牌logo中加入了“北欧棕熊”的形象&#xff0c;并且对此前轮胎标签中的…

qt使用Windows经典风格,以使QTreeView或QTreeWidge有节点线或加号

没有使用Windows经典风格的QTreeView或QTreeWidget显示如下&#xff1a; 使用Windows经典风格的QTreeView或QTreeWidget显示如下&#xff1a; 树展开时&#xff1a; 树未展开时&#xff1a; 可以看到&#xff1a; 未使用Windows经典风格时&#xff0c;QTreeView或QTreeWidget…

【MySQL】基本查询(1)

【MySQL】基本查询&#xff08;1&#xff09; 目录 【MySQL】基本查询&#xff08;1&#xff09;表的增删改查Create单行数据 全列插入多行数据 指定列插入插入否则更新替换 RetrieveSELECT 列全列查询指定列查询查询字段为表达式为查询结果指定别名结果去重 WHERE 条件英语不…

第六篇:视频广告格式上传指南(上) - IAB视频广告标准《数字视频和有线电视广告格式指南》

第六篇&#xff1a; 视频广告格式和上传指南&#xff08;上&#xff09; --- 我为什么要翻译介绍美国人工智能科技公司IAB系列技术标准&#xff08;2&#xff09; 流媒体数字视频的广告格式分为线性和非线性两大类。任何一个广告都可以与显示在视频播放器外部的伴随横幅一起提…

【Linux文件系列】重定向

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

CMake学习(下)

1. 嵌套的CMake 如果项目很大&#xff0c;或者项目中有很多的源码目录&#xff0c;在通过CMake管理项目的时候如果只使用一个CMakeLists.txt&#xff0c;那么这个文件相对会比较复杂&#xff0c;有一种化繁为简的方式就是给每个源码目录都添加一个CMakeLists.txt文件&#xff…

windows系统下python进程管理系统

两年来&#xff0c;我们项目的爬虫代码大部分都是放在公司的windows机器上运行的&#xff0c;原因是服务器太贵&#xff0c;没有那么多资源&#xff0c;而windows主机却有很多用不上。为了合理利用公司资源&#xff0c;降低数据采集成本&#xff0c;我在所以任务机器上使用anac…

将本地的项目上传到gitee,

场景&#xff1a;在本地有一个项目&#xff0c;想要把这个项目上传到gitee&#xff0c;且在gitee中已经创建好仓库 依次执行下图中的命令&#xff1a;

【linux】进程地址空间(进程三)

目录 快速了解&#xff1a;引入最基本的理解&#xff1a;细节&#xff1a;如何理解地址空间&#xff1a;a.什么是划分区域&#xff1a;b.地址空间的理解&#xff1a; 为什么要有进程空间&#xff1f;进一步理解页表与写时拷贝&#xff1a; 快速了解&#xff1a; 先来看这样一段…

2024年起重机司机(限桥式起重机)证考试题库及起重机司机(限桥式起重机)试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年起重机司机(限桥式起重机)证考试题库及起重机司机(限桥式起重机)试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作…

第四范式2023全年业绩:营收人民币42.0亿元同比增长36.4%,行业大模型为千行万业赋能...

3月20日&#xff0c;第四范式&#xff08;06682.HK&#xff09;公布2023年全年业绩&#xff0c;营收稳步增长&#xff0c;盈利节奏清晰。 第四范式定位人工智能时代的软件企业&#xff0c;致力于用人工智能技术赋能千行万业&#xff0c;帮助各行业发现更多规律&#xff0c;形成…

【排序】插入排序与选择排序详解

文章目录 &#x1f4dd;选择排序是什么&#xff1f;&#x1f320;选择排序思路&#x1f309; 直接选择排序&#x1f320;选择排序优化&#x1f320;优化方法&#x1f309;排序优化后问题 &#x1f320;选择排序效率特性 &#x1f309;插入排序&#x1f320;插入排序实现 &#…

day11【网络编程】-综合案例

day11【网络编程】 第三章 综合案例 3.1 文件上传案例 文件上传分析图解 【客户端】输入流&#xff0c;从硬盘读取文件数据到程序中。【客户端】输出流&#xff0c;写出文件数据到服务端。【服务端】输入流&#xff0c;读取文件数据到服务端程序。【服务端】输出流&#xf…

29-3 哥斯拉安装使用

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、哥斯拉 (Godzilla) 介绍 哥斯拉是一个基于流量、HTTP全加密的webshell管理工具,具有以下特点: 内置了3种Payload以及6种加密器,6种支持脚本后缀,20个内置插件基于Java,可…

Java最后一块石头的重量 II(力扣Leetcod1049)

最后一块石头的重量 II 力扣原题 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 x < y。那么粉碎的可能结…

Orbit 使用指南06 | 创建基础环境 | Isaac Sim | Omniverse

如是我闻&#xff1a; 环境将模拟的不同方面如场景、观测和行动空间、重置事件等汇集在一起&#xff0c;为各种应用创建一个连贯的接口。在Orbit中&#xff0c;环境是作为envs.BaseEnv和envs.RLTaskEnv类实现的。这两个类非常相似&#xff0c;但envs.RLTaskEnv对强化学习任务很…