前面说了so文件可以大大减少数据被泄露的情况,但这得是有前提条件。

因为正常的so文件,别人是可以拿到后可以直接在项目中使用的。

那有什么方式可以增加难度,让别人需要一定复杂操作才能使用该so文件库呢?

实现原理

因为c++也是可以获取apk应用签名的,于是这里就可以通过获取的签名来匹配c++本地存放的签名,如果匹配相同则可以继续正常走需要走的逻辑代码。

源码解析

创建需要的java代码

例如:我这里需要一个getKey方法。这里需要有两个参数:

context --> 用于获取签名需要的上下文

type --> 告诉c我获取需要的key对应的类型值

返回值:

String -> 对应的key值

1

2

3

4

5

6

7

8

9

10

11

12

13

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 生成头文件

(注:不会的先别急着点以上链接)

重点强调下这里有坑,因为直接通过javah 将KeyUtil生成.h文件会报如下错误)

1

错误: 无法确定Context的签名

解决方案,先将Context修改为Object类型,如下:

1

public native String getKey(Object context, int type);

然后再进行javah 生成.h文件后,再改回为Context类型就可以了。

创建KeyUtil.cpp 并实现代码

继上面java代码编写cpp代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

/**

* 作者:luck on 2017/1/19 09:26

* 邮箱:fc_dream@163.com

* Ndk_2017_1_19

*/

#include

#include

#include

#include "top_goluck_util_KeyUtil.h"

//该签名是我的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 方法的 ID

jmethodID 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(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);

// 获得签名数组属性的 ID

jfieldID 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(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.可以调用以下代码可以获取

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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 so 签名校验,Android-NDK-之so文件签名校验相关推荐

  1. 03_Android NDK中C语言调用Java代码,javah的使用,javap的使用以及生成签名,Android.mk的编写,C代码的编写

     1  案例场景,通过C语言回调Java的代码,案例的最终界面: 2  案例的代码结构如下: 3 编写DataProvider的代码: package com.example.ndkcallbac ...

  2. Android Studio通过JNI调用NDK程序

    NDK开发,其实是为了项目需要调用底层的一些C/C++的一些东西:另外就是为了效率更加高些,安全性更高. 如果你在Eclipse+ADT下开发过NDK就能体会到要么是配置NDK还要下载Cygwin,配 ...

  3. android digest 认证,探究 Android 签名机制和原理

    背景 最近在调研一个测试工具的使用,在使用中发现被测试工具处理过的apk文件经安装后打开就会崩溃,分析崩溃日志后原因是签名不一致导致的. 说到Android中的签名,可能大家都知道签名的目的就是为了保 ...

  4. Android V3 签名方案,使用密钥转轮为签名更新做准备!

    一.序 在将 App 发布到市场之前,很重要的一个步骤就是为 APK 进行签名,大部分时候,这个操作隐藏在了打包的流程中,而不被我们注意到. 签名的作用,除了证明 App 的所有权之外,还可以帮助 A ...

  5. 【Android】Eclipse自动编译NDK/JNI的三种方法

    [Android]Eclipse自动编译NDK/JNI的三种方法 SkySeraph Sep. 18th  2014 Email:skyseraph00@163.com 更多精彩请直接访问SkySer ...

  6. android+apk+反编译和再签名打包,Android:apk反编译步骤,打包、签名和逆向工程经验总结...

    思路一.apktool1.通过apktool反编译出资源和smaliapktool d MobileManager.apkF:\Android\decompile\apktoolapktool d M ...

  7. [Android] 环境配置之Android Studio开发NDK

    2019独角兽企业重金招聘Python工程师标准>>> ======================================================== 作者:qiu ...

  8. 【Android 安全】DEX 加密 ( Java 工具开发 | apk 文件签名 )

    文章目录 一.生成 jks 文件 二.签名命令 三.执行结果 四.处理 Unsupported major.minor version 52.0 错误 参考博客 : [Android 安全]DEX 加 ...

  9. 文件签名魔塔50层android反编译破解

    发一下牢骚和主题无关: 缘由:该游戏作者有点可爱,原来就是拿别人的游戏,还在游戏中参加积分的轨制,打到20层后,需要积分.看不惯,就把它破解了,打到20层后,直接跳过要积分进程. 本文不提供破解后的安 ...

最新文章

  1. 【android-tips】关于android应用R文件无法读取
  2. nginx请求频率限制模块ngx_http_limit_req_module
  3. 623. 在二叉树中增加一行
  4. windows 和linux查看硬件信息,Linux下如何查看硬件信息?
  5. 你可真行呀的飞鸽传书
  6. C#循环 — break VS continue
  7. python怎样缩进语法边界-Python的基础语法
  8. 面向机器学习的特征工程 七、非线性特征提取和模型堆叠
  9. python回文字符串编程_P086 回文字符串
  10. 服装行业电子商务的概述
  11. 用javascript制作简易的QQ登录网页
  12. php代码加nofollow,给WordPress友情链接添加Nofollow方法详解
  13. 使用Poi-tl 生成word文档 处理word特殊符号方框带勾选 解决方法
  14. python爬虫项目-优美图库
  15. 传递给数据库 'master' 中的日志扫描操作的日志扫描号无效
  16. java 判断是否是手机号码_Java工具类:(1)判断String是否为手机号码
  17. ITE平台开发 chapter4 - https通信
  18. php中define是啥意思
  19. UI妹子说我用CSS实现毛玻璃效果的样子很帅
  20. 欧尼酱讲JVM(23)——垃圾收集器

热门文章

  1. rimraf与windows的rmdir简单使用命令方法
  2. PhpMyWind储存型XSS漏洞练习(CVE-2017-12984)
  3. 【论文笔记】Hierarchical Paired Channel Fusion Network for Street Scene Change Detection
  4. 是时候来了解android7了:通知直接回复
  5. 关于Navicat Premium连接Oracle数据库闪退(失败)的解决办法(带ocl.dll)
  6. iOS中3DTouch的使用
  7. 注解和注解处理器APT
  8. ArcGIS使用(一)创建ArcGIS应用
  9. 合天网安实验室CTF-Steg150-一段欢快的曲调
  10. 智力答题源码php,php儿童智力测评系统