Android-NDK-之so文件签名校验
来源:互联网 发布:备案域名交易平台top 编辑:程序博客网 时间:2024/05/17 21:07
前面说了so文件可以大大减少数据被泄露的情况,但这得是有前提条件。
因为正常的so文件,别人是可以拿到后可以直接在项目中使用的。
因为正常的so文件,别人是可以拿到后可以直接在项目中使用的。
那有什么方式可以增加难度,让别人需要一定复杂操作才能使用该so文件库呢?
下面就为你一一讲解本节的 Android-NDK-之so文件签名校验
实现原理
因为c++也是可以获取apk应用签名的,于是这里就可以通过获取的签名来匹配c++本地存放的签名,如果匹配相同则可以继续正常走需要走的逻辑代码。
源码解析
创建需要的java代码
例如:我这里需要一个getKey方法。这里需要有两个参数:context --> 用于获取签名需要的上下文type --> 告诉c我获取需要的key对应的类型值返回值:String -> 对应的key值
12345678910111213
package top.goluck.util;import android.content.Context;/*** 作者:luck on 2017/1/19 09:05* 邮箱:fc_dream@163.com* Ndk_2017_1_19*/public class KeyUtil {static{System.loadLibrary("goluck");}public native String getKey(Context context, int type);}
实现c语言对应的方法
javah 生成头文件
這里可以参考Android-NDK-之Hello-World来完成
(注:不会的先别急着点以上链接)
重点强调下这里有坑,因为直接通过javah 将KeyUtil生成.h文件会报如下错误)
1
错误: 无法确定Context的签名
解决方案,先将Context修改为Object类型,如下:
1
public native String getKey(Object context, int type);
然后再进行javah 生成.h文件后,再改回为Context类型就可以了。
创建KeyUtil.cpp 并实现代码
继上面java代码编写cpp代码:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
/*** 作者:luck on 2017/1/19 09:26* 邮箱:fc_dream@163.com* Ndk_2017_1_19*///该签名是我的debug包,注:不匹配该签名的apk都不能得到正常的数据// 即调用以下文件只会返回【该so库可能不适用你用!!!】const char *RELEASE_SIGN = "08201dd30820146020101300d06092a864886f70d010105050030373116301406035504030c0d416e64726f69642044656275673110300e060355040a0c07416e64726f6964310b3009060355040613025553301e170d3136303432393038343931365a170d3436303432323038343931365a30373116301406035504030c0d416e64726f69642044656275673110300e060355040a0c07416e64726f6964310b300906035504061302555330819f300d06092a864886f70d010101050003818d00308189028181008d7724d953fac08229e38147379ce329d1054d413eea9ebec5771f0d3e9cf1b6433a6574d25d950277da8b16b43f41167122fac1d372c1abdb0db0cc59f9fc06191a89847e05757afedd33aba94eeecf96044ac12effb562c16d9caf4bbeb42912250138fda5d95e30c99dec6cbd380c1ee297a7eeb97a33af4b657f584844e50203010001300d06092a864886f70d01010505000381810058ad2255854a130850df01b60b9d21bd88c1ab5decdb9bb7940696c74d7f758035ab9d906f9e981aa9214dc6d9bb1cef80483ad735424f2c82915d4eca0cad4a85b984a0dc474b8a9e7c606a401e3d043f1e5ce5fec99d8e0aab72ecb22eaa3494b84f166e3e4aa382d2bda87a44c7f38d5aa2354e5f299f72c85665cb9707a6";JNIEXPORT jstring JNICALL Java_top_goluck_util_KeyUtil_getKey(JNIEnv *env, jobject object, jobject contextObject,jint type) {//-----以下验证签名逻辑主要方法 今天所讲的主题主要代码jclass native_class = env->GetObjectClass(contextObject);jmethodID pm_id = env->GetMethodID(native_class, "getPackageManager","()Landroid/content/pm/PackageManager;");jobject pm_obj = env->CallObjectMethod(contextObject, pm_id);jclass pm_clazz = env->GetObjectClass(pm_obj);// 得到 getPackageInfo 方法的 IDjmethodID package_info_id = env->GetMethodID(pm_clazz, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");jclass native_classs = env->GetObjectClass(contextObject);jmethodID mId = env->GetMethodID(native_classs, "getPackageName","()Ljava/lang/String;");jstring pkg_str = static_cast<jstring>(env->CallObjectMethod(contextObject, mId));// 获得应用包的信息jobject pi_obj = env->CallObjectMethod(pm_obj, package_info_id, pkg_str, 64);// 获得 PackageInfo 类jclass pi_clazz = env->GetObjectClass(pi_obj);// 获得签名数组属性的 IDjfieldID signatures_fieldId = env->GetFieldID(pi_clazz, "signatures","[Landroid/content/pm/Signature;");jobject signatures_obj = env->GetObjectField(pi_obj, signatures_fieldId);jobjectArray signaturesArray = (jobjectArray) signatures_obj;jsize size = env->GetArrayLength(signaturesArray);jobject signature_obj = env->GetObjectArrayElement(signaturesArray, 0);jclass signature_clazz = env->GetObjectClass(signature_obj);jmethodID string_id = env->GetMethodID(signature_clazz, "toCharsString","()Ljava/lang/String;");jstring str = static_cast<jstring>(env->CallObjectMethod(signature_obj, string_id));char *c_msg = (char *) env->GetStringUTFChars(str, 0);if (strcmp(c_msg, RELEASE_SIGN) == 0)//如果当前apk的签名一致返回需要数据//----以上验证签名逻辑主要方法{if (type == 1) {return env->NewStringUTF("我是通过native方法返回的QQKey");} else if (type == 2) {return env->NewStringUTF("我是通过native方法返回的WeiXinKey");} else {return env->NewStringUTF("error,没有该类型的Key");}} else {return env->NewStringUTF("该so库可能不适合你用!!!");}}
可根据需求自行修改以上代码。
so文件签名
获取正式项目的签名:
1.可以调用以下代码可以获取
1234567891011121314
public static String getSignature(Context context)try {/** 通过包管理器获得指定包名包含签名的包信息 **/PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);/******* 通过返回的包信息获得签名数组 *******/Signature[] signatures = packageInfo.signatures;/******* 循环遍历签名数组拼接应用签名 *******/return signatures[0].toCharsString();/************** 得到应用签名 **************/} catch (PackageManager.NameNotFoundException e) {e.printStackTrace();}return null;}
2.利用第三方软件获取,如微信获取签名apk
修改cpp中RELEASE_SIGN值
修改cpp中RELEASE_SIGN值 为上面的签名值。
以上就完成所有so文件的编写代码的步骤了。
生成so文件正式项目使用
这里不再重复了,可参考Android-NDK-之Hello-World
阅读全文
0 0
- Android-NDK-之so文件签名校验
- Android 使用jni校验应用签名sha1值,防止so文件逆向盗用
- Android NDK生成so文件
- Android-NDK编译.so文件
- Android逆向之115网盘5.3.0apk签名校验so破解并干掉长广告
- Android之SDK、NDK、JNI和so文件
- Android之SDK、NDK、JNI和so文件
- Android之SDK、NDK、JNI和so文件
- Android之SDK、NDK、JNI和so文件
- Android NDK开发之 NDK类型签名
- ndk开发之利用android系统中.so库文件(例:libsqlite.so)
- android NDK编译多个so文件
- android NDK入门实例,生成.so文件
- android — NDK生成so文件
- android NDK编译多个so文件
- android NDK编译多个so文件
- Android NDK 生成、调用so文件
- android 使用 ndk生成.so文件
- Java 创建线程的方法2
- java抽象类
- 开启数据科学生涯的45种方式
- NOI2002银河英雄传说 并查集
- Unity 游戏框架搭建 (十四) 优雅的QSignleton(零) QuickStart
- Android-NDK-之so文件签名校验
- Spring 4.2.2以上版本和swagger集成方案和踩过的坑
- 遇到版本号判断的一个原则
- 第一个安卓驱动程序
- Vue中使用vux的配置,分为两种情况:
- Windows Server2008 R2安装Mysql5.7.19时遇到问题:
- Mapreduce实现MapSideJoin
- Word Count (Map Reduce)
- Kotlin 一统天下?Kotlin/Native 开始支持 iOS 和 Web 开发