1. 程式人生 > >Android-NDK-之so檔案簽名校驗

Android-NDK-之so檔案簽名校驗

前面說了so檔案可以大大減少資料被洩露的情況,但這得是有前提條件。
因為正常的so檔案,別人是可以拿到後可以直接在專案中使用的。

那有什麼方式可以增加難度,讓別人需要一定複雜操作才能使用該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 * 郵箱:[email protected] * 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程式碼:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 /** * 作者:luck on 2017/1/19 09:26 * 郵箱:[email protected] * Ndk_2017_1_19 */#include <jni.h>#include <string.h>#include <stdio.h>#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<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); // 獲得簽名陣列屬性的 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<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-so檔案名校

前面說了so檔案可以大大減少資料被洩露的情況,但這得是有前提條件。因為正常的so檔案,別人是可以拿到後可以直接在專案中使用的。那有什麼方式可以增加難度,讓別人需要一定複雜操作才能使用該so檔案庫呢? 實現原理 因為c++也是可以獲取apk應用簽名的,於是這裡就可以

六、Android安全機制NDK實現防鉤子名校

//對公鑰MD5後進行比對驗證 void MD5_Check(char *src) { char buff[3] = {'\0'}; char hex[33] = {'\0'}; unsigned char digest[MD5_DIGEST_LENGTH]; MD5_CTX ctx; MD5_Ini

Android安全/應用逆向--32--破解NDK層的名校

7-9、破解NDK層的簽名校驗 NDK層簽名校驗破解的思路與Java層簽名校驗破解的思路相似: (1) 通過輸入“signature”關鍵字定位獲取本Apk簽名信息的函式(在下文中,我們用getApkSign來標記該函式); (2) 找出呼叫的getApkSig

Android中JNI使用詳解(1)---Eclipse中NDK配置So檔案生成

1、NDK下載和配置 NDK下載地址:http://www.androiddevtools.cn/ NDK下載完成後,選擇Eclipse上方Window選單Preferences - Android - NDK 在NDK&nb

AndroidNDKso檔案產生和使用

使用工具:eclipse 1.生成so檔案 1.1.開啟Eclipse,新建一個Android工程 FileàNewàAndroid Application Project 一路Next下去,直到Finish。 1.2.新增so檔案 工程右鍵--Android Too

Android NDK編譯本地檔案以及引用第三方so檔案

引用第三方的so檔案很簡單,在工程目錄的libs資料夾下新建資料夾armeabi,以及armeabi-v7a,然後將要引用的so檔案分別複製到這兩個 資料夾下就行了。但是有時候我們會使用第三方開源演算法,或者本地的底層程式碼,那麼在呼叫這些程式碼的介面時就需要將這些程式碼編

Android APK 名校

非對稱加密演算法 非對稱加密演算法需要兩個金鑰:公開金鑰(簡稱公鑰)和私有金鑰(簡稱私鑰)。公鑰與私鑰是一對,如果用公鑰對資料進行加密,只有用對應的私鑰才能解密;如果用私鑰對資料進行加密,那麼只有用對應的公鑰才能解密。因為加密和解密使用的是兩個不同的金鑰,所以這種演算法

如何在Android中增加自己的應用名校

背景: 我最近的遇到一個專案,需要在PMS中增加廠商自己的應用簽名校驗,本文將描述整個新增過程。 Android使用Java的數字證書相關的機制來給apk加蓋數字證書,要理解Android數字證書,需要先了解以下數字證書的概念和java的數字證書機制。 1

Android Studio NDKso檔案開發 以及常見錯誤

LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := demo LOCAL_SRC_FILES := demo.cpp include $(BUILD_SHARED_LIBRARY) andr

Android Studio NDKso檔案開發(一)

部落格借鑑: 前言: 1、什麼是NDK? NDK全稱是Native Development Kit,NDK提供了一系列的工具,幫助開發者快速開發C(或C++)的動態庫,並能自動將so和java應用一起打包成apk。NDK集成了交叉編譯器(交叉編譯器

Android app去掉https名校

ins not found ride sslsocket 自建 server 解決辦法 bool android 本文同步至http://javaexception.com/archives/30 問題: 之前的一個開源項目碰到了一個問題,Fix CertPathVal

Android NDK Hello World

module path package ren ide string style activity code 首先編寫Jni接口的c文件,此文件命名有些特殊,具體的命名方式可以參考文檔來做。 #include <jni.h> #include <stri

php+js 防止被抓包篡改資料,資料名校

簽名金鑰,這個是自己生成的,需要客戶端+服務端一致。 <?php /** * 獲取簽名 * @param $data 提交的資料 * @param $key 安全金鑰 * @return bool */ function signature($data, $key) {

名詞解釋第六十九講:名校

這裡是王團長區塊鏈學院,與最優秀的區塊鏈人一起成長!今天給大家講講簽名校驗。   簽名校驗其實是區塊鏈裡的兩個詞語—簽名和校驗。簡單的說,簽名是用來證明你是你,校驗則是別人來驗證你是否真的是你。   說到簽名,很多人的第一反應是用筆簽名。生活中我們經常需要用筆簽名

Android中JNI使用詳解(3)---Android Studio中SO檔案生成

Android中JNI使用詳解(2)---Android Studio中SO檔案生成 上一篇寫到過在Android Studio中配置NDK環境地址:Android Studio中NDK環境配置 這篇文章講解在Android Studio中

Android NDKHelloJni工程遇到的問題

今天想自己新建一個NDK的工程來跑一跑試試,在整個過程中遇到了不少問題,把一些在網上沒找到方案、自己解決了的問題記錄一下。 參照的教程來自http://www.cnblogs.com/devinzhang/archive/2012/02/29/2373729.html,絕對是良心教程。

Android複習旅--檔案儲存

內部儲存 內部儲存是指將應用程式中的資料以檔案方式儲存到裝置的內部儲存空間中(該檔案位於 data/data// 目錄下)。 一般情況下應用儲存在記憶體下的資料其他應用是訪問不了的,當您希望確保使用者或其他應用均無法訪問您的檔案時,內部儲存是最佳選擇。使用者解除安裝

Android實戰R檔案

開始遇到R檔案缺失,在網上社群查閱了資料,大概有三種方法: clean project,然後rebuild 選擇專案properties,點選Android,選擇相應版本,點選ok 修改res檔案下的錯誤 我遇到的問題是匯入包版本錯誤,選擇了正確的版本,就生

筆記80 | Eclipse環境下利用NDK編譯SO檔案

準備 1.Eclipse工作環境 2.NDK 下載地址 ,選擇一個版本對應下載之後解壓,注意路徑不要有中文,請直接使用版本【android-ndk-r14b】,不要問為什麼,都是淚; 然後再環境變數的path中新增路徑;如圖 接著cmd中輸入ndk-build

Android studio 編譯.so檔案生成 No rule to make target

之前有接觸過jni相關的一些東西,今天趁著時間,自己做了一下編譯jni的環境搭建。沒想到遇到各種問題,下面將問題給拿出來做個記錄,以後好避免這些問題。 1、首先我是通過編寫.mk檔案去編譯.so檔案的,而不是現在的Cmake去編譯.so。 2、我由於之前一直有在網上看jni如果編譯.so ,