基于sha1算法的登陆协议分析
2016-07-03 21:55
423 查看
1、整体分析
登陆抓包分析如下:其中密码为:123456
可以看到对密码进行了加密,最后添加了封包签名加密
2、加密算法java层分析
定位到java关键代码如下:public void loginCellFromRemote(final String paramString1, final String paramString2, String paramString3, final IUserManager.LogInCallback paramLogInCallback) throws WrongUserDataException { if (paramLogInCallback == null) { throw new NullPointerException("callback is null!"); } Log.e("dss", "params = "); String str1 = this.deviceUserInfo.getDeviceId(); String str2 = Md5Util.stringMd5(paramString2); RequestParams localRequestParams = new RequestParams(); localRequestParams.add("code", paramString3); localRequestParams.add("device_id", str1); localRequestParams.add("mobile", paramString1); localRequestParams.add("pawd", str2); paramString3 = YoyoJieUtils.getTimeStamp(); localRequestParams.add("timestamp", paramString3); ArrayList localArrayList = new ArrayList(); localArrayList.add(new CmsTopUtils.UrlParameterBean("device_id", str1)); localArrayList.add(new CmsTopUtils.UrlParameterBean("mobile", paramString1)); localArrayList.add(new CmsTopUtils.UrlParameterBean("pawd", str2)); localArrayList.add(new CmsTopUtils.UrlParameterBean("timestamp", paramString3)); localRequestParams.add("sign", YoyoJieUtils.getSign(localArrayList, "oJf9prlOH3pmT5C87R2o82PLz#@uf^")); Log.e("dss", "params = " + localRequestParams); .............. }
可以看到密码加密算法为:
Md5Util.stringMd5
sign签名加密算法为:
YoyoJieUtils.getSign(localArrayList, "oJf9prlOH3pmT5C87R2o82PLz#@uf^"));
其中,密码就是简单的MD5加密,如下:
public static String stringMd5(String paramString) { try { MessageDigest localMessageDigest = MessageDigest.getInstance("MD5"); localMessageDigest.update(paramString.getBytes()); paramString = HexUtil.byteToHexString(localMessageDigest.digest()).toLowerCase(); return paramString; } catch (NoSuchAlgorithmException paramString) { paramString.printStackTrace(); } return null; }
而sign签名算法为:
public static String getSign(List<CmsTopUtils.UrlParameterBean> paramList, String paramString) { Log.i("ASD", "加密了"); return KeyGenerator.generateKeyByParams(getSignString(paramList)); }
public static native String generateKeyByParams(String paramString) throws IllegalArgumentException;
下面分析native层的generateKeyByParams函数
3、加密算法native层分析
整理后的代码为:int __fastcall generateKeyByParams(JNIEnv_ *a1, jclass clazz, jstring input) { int v3; // r3@2 _JNIEnv *env; // [sp+Ch] [bp-48h]@1 char v6[4]; // [sp+14h] [bp-40h]@1 int v7; // [sp+18h] [bp-3Ch]@1 int v8; // [sp+1Ch] [bp-38h]@1 int v9; // [sp+20h] [bp-34h]@1 int v10; // [sp+24h] [bp-30h]@1 int v11; // [sp+28h] [bp-2Ch]@1 int v12; // [sp+2Ch] [bp-28h]@1 int v13; // [sp+30h] [bp-24h]@1 int v14; // [sp+34h] [bp-20h]@1 int v15; // [sp+38h] [bp-1Ch]@1 char v16; // [sp+3Ch] [bp-18h]@1 jboolean isCopy; // [sp+3Fh] [bp-15h]@1 int v18; // [sp+40h] [bp-14h]@3 int v19; // [sp+44h] [bp-10h]@2 unsigned __int8 v20; // [sp+4Bh] [bp-9h]@1 int v21; // [sp+4Ch] [bp-8h]@1 env = (_JNIEnv *)a1; isCopy = 0; v21 = _JNIEnv::GetStringUTFChars(&a1->functions, input, &isCopy); *(_DWORD *)v6 = 0; v7 = 0; v8 = 0; v9 = 0; v10 = 0; v11 = 0; v12 = 0; v13 = 0; v14 = 0; v15 = 0; v16 = 0; v20 = generate_key_by_value(v21, (int)v6); if ( v20 ^ 1 ) { v19 = _JNIEnv::FindClass(env, "java/lang/IllegalArgumentException"); _JNIEnv::ThrowNew(env, v19, "thrown from C code"); v3 = 0; } else { v18 = _JNIEnv::NewStringUTF(env, v6); v3 = v18; } return v3; }
该函数的流程为:
1、将输入的字符串转换成char*字符串。
2、generate_key_by_value函数对字符串加密。
signed int __fastcall generate_key_by_value(char *input, int a2) { char *inputStr; // ST04_4@1 signed int v3; // r4@3 unsigned int v4; // r0@5 std::string *v5; // r0@7 int v6; // r4@7 std::string *v7; // r0@7 int v8; // r0@7 int v9; // r0@7 int v10; // r4@7 int v11; // r0@7 int v12; // r0@7 int v14; // [sp+0h] [bp-F4h]@1 char v15; // [sp+8h] [bp-ECh]@6 int j; // [sp+64h] [bp-90h]@6 char v17; // [sp+68h] [bp-8Ch]@9 char *v18; // [sp+7Ch] [bp-78h]@1 char v19; // [sp+88h] [bp-6Ch]@1 char v20; // [sp+8Ch] [bp-68h]@1 char v21; // [sp+A4h] [bp-50h]@1 char v22; // [sp+A8h] [bp-4Ch]@1 char v23; // [sp+ACh] [bp-48h]@1 char v24; // [sp+B0h] [bp-44h]@1 char v25; // [sp+B4h] [bp-40h]@4 char v26; // [sp+BCh] [bp-38h]@4 char v27; // [sp+C4h] [bp-30h]@4 char v28; // [sp+CCh] [bp-28h]@4 char v29; // [sp+D0h] [bp-24h]@4 int v30; // [sp+D4h] [bp-20h]@8 int v31; // [sp+D8h] [bp-1Ch]@2 std::string *v32; // [sp+DCh] [bp-18h]@2 int k; // [sp+E0h] [bp-14h]@9 unsigned int i; // [sp+E4h] [bp-10h]@1 char v35[12]; // [sp+E8h] [bp-Ch]@10 inputStr = input; v14 = a2; std::map<std::string,std::string,order_by_inc,std::allocator<std::pair<std::string const,std::string>>>::map(&v20); std::allocator<char>::allocator(&v21); // 输入字符串 std::string::string(&v19, inputStr, (int)&v21); std::allocator<char>::~allocator(&v21); std::string::string((std::string *)&v22, (const std::string *)&v19); std::allocator<char>::allocator(&v24); std::string::string(&v23, (const char *)&unk_68F84, (int)&v24);// 分隔符& split((int)&v18, (std::string *)&v22, (std::string *)&v23);// 利用分割符&,对输入的字符串进行分割 std::string::~string((std::string *)&v23); std::allocator<char>::~allocator(&v24); std::string::~string((std::string *)&v22); for ( i = 0; ; ++i ) { v4 = std::vector<std::string,std::allocator<std::string>>::size(&v18);// 分割后数组的长度 if ( v4 <= i ) // 判断是否超过了数组长度 break; v32 = (std::string *)std::vector<std::string,std::allocator<std::string>>::operator[](&v18, i);// 获取每一项 v31 = std::string::find(v32, (const char *)&unk_68F88, 0);// 查找 = if ( v31 == -1 ) { v3 = 0; goto LABEL_13; } std::string::substr(&v28, v32, 0, v31); // =前面的字符串 std::string::substr(&v29, v32, v31 + 1, -1);// =后面的字符串 std::make_pair<std::string,std::string>(&v27, &v28, &v29);// 键值对 std::pair<std::string const,std::string>::pair<std::string,std::string>(&v26, &v27); std::map<std::string,std::string,order_by_inc,std::allocator<std::pair<std::string const,std::string>>>::insert( &v25, &v20, &v26); // 插入map std::pair<std::string const,std::string>::~pair(&v26); std::pair<std::string,std::string>::~pair(&v27); std::string::~string((std::string *)&v29); std::string::~string((std::string *)&v28); } SHA1Init(&v15); SHA1Update(&v15, "bi2ipxazqodmw9hoety0h1wwgjvkttng", 32);// 对输入的字符串加密前,先进行一次自定义的字符串加密 for ( j = std::map<std::string,std::string,order_by_inc,std::allocator<std::pair<std::string const,std::string>>>::begin(&v20); ; std::_Rb_tree_iterator<std::pair<std::string const,std::string>>::operator++(&j) )// 遍历上面的获取的map中的每一项 { v30 = std::map<std::string,std:: b667 string,order_by_inc,std::allocator<std::pair<std::string const,std::string>>>::end(&v20); if ( !std::_Rb_tree_iterator<std::pair<std::string const,std::string>>::operator!=(&j, &v30) ) break; v5 = (std::string *)std::_Rb_tree_iterator<std::pair<std::string const,std::string>>::operator->(&j); v6 = std::string::c_str(v5); // 获取的值 v7 = (std::string *)std::_Rb_tree_iterator<std::pair<std::string const,std::string>>::operator->(&j); v8 = std::string::size(v7); // 值的长度 SHA1Update(&v15, v6, v8); v9 = std::_Rb_tree_iterator<std::pair<std::string const,std::string>>::operator->(&j); v10 = std::string::c_str((std::string *)(v9 + 4));// 将值往后移动4位 v11 = std::_Rb_tree_iterator<std::pair<std::string const,std::string>>::operator->(&j); v12 = std::string::size((std::string *)(v11 + 4));// 将值往后移动4位的长度 SHA1Update(&v15, v10, v12); } SHA1Update(&v15, "bi2ipxazqodmw9hoety0h1wwgjvkttng", 32);// 结尾再加密自定义字符串 // SHA1Final(&v17, &v15); for ( k = 0; k <= 19; ++k ) sprintf((char *)(v14 + 2 * k), "%02x", (unsigned __int8)v35[k - 128]); v3 = 1; LABEL_13: std::vector<std::string,std::allocator<std::string>>::~vector(&v18); std::string::~string((std::string *)&v19); std::map<std::string,std::string,order_by_inc,std::allocator<std::pair<std::string const,std::string>>>::~map(&v20); return v3; }
里面我已经添加了详细的注释,应该比较简单,原理为:对输入的字符串,利用&分割,然后再分解=左右的字符串,存入map,最后遍历每个map值,进行加密。其中在加密前后,附加盐
相关文章推荐
- 详解HDFS Short Circuit Local Reads
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- 用ASP编写的加密和解密类
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- VBS脚本加密/解密VBS脚本(简易免杀版1.1)
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- BAT加密工具 EncryBat 非编译型bat批处理加密方案与代码
- C#对称加密(AES加密)每次生成的结果都不同的实现思路和代码实例
- SQLServer 2008中的代码安全(一) 存储过程加密与安全上下文
- C#算法函数:获取一个字符串中的最大长度的数字
- 实例讲解SQL Server加密功能
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#实现对文件进行加密解密的方法
- C#实现数据包加密与解密实例详解
- C#冒泡法排序算法实例分析
- C#最简单的字符串加密解密方法