参考文章(http://www.pocketdigi.com/20141129/1398.html)真心感谢这位朋友,他的代码可以正常跑通,网上其他人也有类似的代码,但是都报错,这几天弄这个NDK签名 很折磨人啊
通过包名和签名的比对,可以防止so库被其他人二次打包。代码整理如下:
Java中获取应用签名hashcode
public static int getSignature(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(
"com.test", PackageManager.GET_SIGNATURES);
Signature[] signs = packageInfo.signatures;
Signature sign = signs[0];
return sign.hashCode();
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
Android.mk
APP_ABI := all
APP_PLATFORM := android-15
Application.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := my-jni
LOCAL_SRC_FILES := my-jni.c
#用来打印Android日志信息
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
my-jni.c
#include
#include
#include
#define LOG_TAG "native_log"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
//合法的APP包名
const char *app_packageName = "com.test";
//合法的hashcode
const int app_signature_hash_code = 1836652225;
/**
* 校验APP 包名和签名是否合法 返回值为1 表示合法
*/
jint checkSignature(JNIEnv *env, jobject thiz, jobject context) {
//Context的类
jclass context_clazz = (*env)->GetObjectClass(env, context);
// 得到 getPackageManager 方法的 ID
jmethodID methodID_getPackageManager = (*env)->GetMethodID(env,
context_clazz, "getPackageManager",
"()Landroid/content/pm/PackageManager;");
// 获得PackageManager对象
jobject packageManager = (*env)->CallObjectMethod(env, context,
methodID_getPackageManager);
获得 PackageManager 类
jclass pm_clazz = (*env)->GetObjectClass(env, packageManager);
// 得到 getPackageInfo 方法的 ID
jmethodID methodID_pm = (*env)->GetMethodID(env, pm_clazz, "getPackageInfo",
"(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
//
得到 getPackageName 方法的 ID
jmethodID methodID_pack = (*env)->GetMethodID(env, context_clazz,
"getPackageName", "()Ljava/lang/String;");
// 获得当前应用的包名
jstring application_package = (*env)->CallObjectMethod(env, context,
methodID_pack);
const char *package_name = (*env)->GetStringUTFChars(env,
application_package, 0);
LOGE("packageName: %s\n", package_name);
// 获得PackageInfo
jobject packageInfo = (*env)->CallObjectMethod(env, packageManager,
methodID_pm, application_package, 64);
jclass packageinfo_clazz = (*env)->GetObjectClass(env, packageInfo);
jfieldID fieldID_signatures = (*env)->GetFieldID(env, packageinfo_clazz,
"signatures", "[Landroid/content/pm/Signature;");
jobjectArray signature_arr = (jobjectArray)(*env)->GetObjectField(env,
packageInfo, fieldID_signatures);
//Signature数组中取出第一个元素
jobject signature = (*env)->GetObjectArrayElement(env, signature_arr, 0);
//读signature的hashcode
jclass signature_clazz = (*env)->GetObjectClass(env, signature);
jmethodID methodID_hashcode = (*env)->GetMethodID(env, signature_clazz,
"hashCode", "()I");
jint hashCode = (*env)->CallIntMethod(env, signature, methodID_hashcode);
LOGE("hashcode: %d\n", hashCode);
if (strcmp(package_name, app_packageName) != 0) {
return -1;
}
if (hashCode != app_signature_hash_code) {
return -2;
}
return 1;
}