APP官网下载地址:
https://jz.yofish.com/homepage.html
首先,调用抓包工具,获取参数:
参数列表:
mobileNo:xxxx 手机号
source:12034 多次测试,发现该字段固定,版本类
cgetuiid:4767890aab8d5a38bd36dd165d981ede 多次测试,发现字段固定,应为设备ID类
cmodel:HD1900 设备型号
pwd:3b503f7e87b9f2e66c52001afe76adc6 密码的md5
signMsg:EB10FF224AFFBDCD1EEF2AC01CA584EB sign的md5
cxmid:xSO3/z+G4coGDJF5NySVvaBKFyMtw2DDKS8ds1IKjA8ydscVTHurmTAoa7Fk3Xj3 设备类参数,不变
cimei:865166028805691 imei字段 需要与协议头一致
cres:540*960 分辨率
merchantacctId:130313002 多次测试,发现固定不变,猜测版本号
signType:1 加密类型,固定为1
cphoneos:Android_5.1.1_LMY49I 系统型号,固定
cphonebrand:OnePlus 系统型号固定
cuserid:36df3e97-0ffe-4073-a92e-f89da19ddea5 随机的uuid,需要与协议头一致
header协议头:
appversion: 5.0.0 APP版本5.0
flavor: youyu app标识
releaseversion: 5.0.0 APP版本
source: 12034 app版本标识
cuserid: 36df3e97-0ffe-4073-a92e-f89da19ddea5 uuid,与传参一致
devtype: android 手机类型,安卓
apppkgname: com.jz.youyu app包名
appversionname: 5.0.0 版本
appversioncode: 202 版本
product: %E6%9C%89%E9%B1%BC%E8%AE%B0%E8%B4%A6 解码:有鱼记账
device: OnePlusHD1900 设备型号
channel: %E5%AE%98%E7%BD%91 解码:官网
deviceid: 865166028805691 设备imei,需要与传参一致
content-type: application/x-www-form-urlencoded 提交类型
user-agent: okhttp/3.12.1 协议头
拖入idax,进行源码反编译
抓包分析参数后,我们要查的是signMsg,所以搜索关键词signMsg
image.png
第一次查找的是signMsg,关键词太多,通过"signMsg"过滤后,就很少的,第一个进去看后,感觉不是
image.png
与提交的参数不一致,可能是别的参数,跳过,看下一个
image.png
根据上方变量猜测得知,这里的确是,我们看一下谁调用了这个变量
image.png
很明显,就2个方法,第一个是变量,第二个是函数,直接看函数
image.png
看了一下,很像,对比一下这几个参数
f20085g merchantacctId
f20083e mobileNo
f20084f pwd
k signMsg
很明显了,就是这个函数内进行参数处理的
image.png
StringBuilder sb = new StringBuilder();
sb.append("signType=1" + "&merchantacctId=" + f20081c + "&mobileNo=" + str2 + "&pwd=" + str);
sb.append("&key=");
sb.append(f20082d);
String a2 = bd.a(sb.toString(), true);
定义字符串数组sb,追加参数:
signType=1&merchantacctId=f20081c &mobileNo=str2&pwd=str&key=f20082d
通过该方法可知
f20081c 为固定参数,看一下他的值
f20081c=130313002
str2手机号
str密码
f20082d md5秘钥,看一下是多少 A9FK25RHT487ULMI
所以,实际要进行md5的字段为:
signType=1&merchantacctId=130313002&mobileNo=手机号码&pwd=密码&key=A9FK25RHT487ULMI
通过参数模拟,写一个java类,校验一下我们的猜测是否正确
image.png
对比抓包结果:
image.png
一致,所以signMsg参数无误,那么接下来,对密码直接进行md5,发现与post的结果不一致,根据函数传参可知,密码是在加密后传到这个函数来的,所以我们再查一下是谁调用了他
image.png
通过节点命名,唯一的Login函数,肯定就是登陆类,进去看看
image.png
可知,的确是这里传的
String obj = this.j.getText().toString();
final String a2 = bd.a(obj.trim() + l, false);
通过刚刚的函数分析可知,bd.a是个md5,右边的布尔值,应该为是否对接过进行大写,我们看一下l参数
private static final String l = "http://www.9188.com/";
也就是加密内容为:
trim(密码)+ "http://www.9188.com/"
对比md5,结果正常,postman模拟请求:
成功,请求成功,登陆算法获取完成
附:java 加密demo:
import java.util.Locale;
import java.security.MessageDigest;
public class Demo {
//盐,用于混交md5
private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
public static void main(String[] args) {
//字符串加密后,就是登陆的signMsg参数 注意,结果要进行大写转换!
System.out.println(getSign("您的手机号","您的密码"));
}
/**
* 获取signMsg的加密字段
* @return
*/
public static String getSign(String str2,String str) {
String f20081c="130313002"; //项目标识 等同 merchantacctId
//需要对md5进行一个加密
String f20082d="A9FK25RHT487ULMI"; //秘钥
StringBuilder sb = new StringBuilder();
//对密码进行md5
str=getPwdMd5(str);
sb.append("signType=1" + "&merchantacctId=" + f20081c + "&mobileNo=" + str2 + "&pwd=" + str);
sb.append("&key=");
sb.append(f20082d);
String sign_text=sb.toString();
//字符串加密后,就是登陆的signMsg参数 注意,结果要进行大写转换!
System.out.println("加密字符串"+sign_text);
return encodeByMD5(sign_text,Boolean.TRUE);
}
private static String encodeByMD5(String originString,Boolean type) {
if (originString != null){
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] results = md.digest(originString .getBytes());
String resultString = byteArrayToHexString(results);
if (type==Boolean.TRUE){
return resultString.toUpperCase();
}else{
return resultString;
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
return null;
}
/**
* 转换字节数组为16进制字串
*
* @param b 字节数组
* @return 十六进制字串
*/
private static String byteArrayToHexString(byte[] b) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}
/**
* 将一个字节转化成16进制形式的字符串
* @param b
* @return
*/
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n = 256 + n;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
/**
* 获取密码的md5
*/
public static String getPwdMd5(String pwd) {
String key="http://www.9188.com/"; //密码加密秘钥
//字符串加密后,就是登陆的signMsg参数 注意,结果要进行大写转换!
System.out.println("加密字符串:"+pwd+key);
return encodeByMD5(pwd+key,Boolean.FALSE);
}
}
网友评论