通过jni获取应用签名
SignUtil.h
#ifndef BWL_SIGN_UTIL_H #define BWL_SIGN_UTIL_H #include <jni.h> // 获取当前应用的签名 char *getSign(JNIEnv *env); #endif //BWL_SIGN_UTIL_H
SignUtil.cpp
// // Created by wenlongbai on 8/15/17. // #include <malloc.h> #include <string.h> #include "SignUtil.h" #include "Util.h" // http://blog.csdn.net/gaoshouxiaodi/article/details/37821659 jobject getApplication(JNIEnv *env) { jclass localClass = env->FindClass("android/app/ActivityThread"); if (localClass != NULL) { jmethodID getapplication = env->GetStaticMethodID(localClass, "currentApplication", "()Landroid/app/Application;"); if (getapplication != NULL) { jobject application = env->CallStaticObjectMethod(localClass, getapplication); return application; } return NULL; } return NULL; } char *getDefaultSign() { int len = strlen(APP_SIGN_LAUNCHER); char *defaultSign = (char *) malloc(len + 1); strcpy(defaultSign, APP_SIGN_LAUNCHER); return defaultSign; } char *getSign(JNIEnv *env) { LOGI("getSign start"); jobject context = getApplication(env); if (context == NULL) { LOGI("getSign: not found context, return default value"); return getDefaultSign(); } jclass activity = env->GetObjectClass(context); // 得到 getPackageManager 方法的 ID jmethodID methodID_func = env->GetMethodID(activity, "getPackageManager", "()Landroid/content/pm/PackageManager;"); // 获得PackageManager对象 jobject packageManager = env->CallObjectMethod(context, methodID_func); jclass packageManagerclass = env->GetObjectClass(packageManager); //得到 getPackageName 方法的 ID jmethodID methodID_pack = env->GetMethodID(activity, "getPackageName", "()Ljava/lang/String;"); //获取包名 jstring name_str = static_cast<jstring>(env->CallObjectMethod(context, methodID_pack)); // 得到 getPackageInfo 方法的 ID jmethodID methodID_pm = env->GetMethodID(packageManagerclass, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); // 获得应用包的信息 jobject package_info = env->CallObjectMethod(packageManager, methodID_pm, name_str, 64); // 获得 PackageInfo 类 jclass package_infoclass = env->GetObjectClass(package_info); // 获得签名数组属性的 ID jfieldID fieldID_signatures = env->GetFieldID(package_infoclass, "signatures", "[Landroid/content/pm/Signature;"); // 得到签名数组,待修改 jobject signatur = env->GetObjectField(package_info, fieldID_signatures); jobjectArray signatures = reinterpret_cast<jobjectArray>(signatur); // 得到签名 jobject signature = env->GetObjectArrayElement(signatures, 0); // 获得 Signature 类,待修改 jclass signature_clazz = env->GetObjectClass(signature); // 获取toByteArray方法ID jmethodID signature_method_toByteArray = env->GetMethodID(signature_clazz, "toByteArray", "()[B"); jobject signatureBytes = env->CallObjectMethod(signature, signature_method_toByteArray); // 获取InputStream对象 jclass inputStreamClass = env->FindClass("java/io/ByteArrayInputStream"); jobject inputStreamObj = env->NewObject( inputStreamClass, env->GetMethodID(inputStreamClass, "<init>", "([B)V"), signatureBytes ); // 获取CertificateFactory对象 jclass certificateClass = env->FindClass("java/security/cert/CertificateFactory"); jmethodID certificateClass_getInstance = env->GetStaticMethodID(certificateClass, "getInstance", "(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;"); jobject certificateFactoryObj = env->CallStaticObjectMethod(certificateClass, certificateClass_getInstance, env->NewStringUTF("X509")); // 生成X509Certificate对象 jmethodID certificateFactoryClass_method_generateCertificate = env->GetMethodID( certificateClass, "generateCertificate", "(Ljava/io/InputStream;)Ljava/security/cert/Certificate;"); jobject x509CertificateObj = env->CallObjectMethod(certificateFactoryObj, certificateFactoryClass_method_generateCertificate, inputStreamObj); // 获取X509Certificate的c.getEncoded数据 jmethodID X509Certificate_method_getEncoded = env->GetMethodID( env->FindClass("java/security/cert/Certificate"), "getEncoded", "()[B"); jobject x509CertificateObj_encoded = env->CallObjectMethod(x509CertificateObj, X509Certificate_method_getEncoded); // 生成MessageDigest jclass MessageDigestClass = env->FindClass("java/security/MessageDigest"); jmethodID MessageDigestClass_getInstance = env->GetStaticMethodID(MessageDigestClass, "getInstance", "(Ljava/lang/String;)Ljava/security/MessageDigest;"); jobject MessageDigestObj = env->CallStaticObjectMethod(MessageDigestClass, MessageDigestClass_getInstance, env->NewStringUTF("SHA1")); // 获取MessageDigestObj.digest jmethodID MessageDigestClass_method_digest = env->GetMethodID(MessageDigestClass, "digest", "([B)[B"); jobject publicKey = env->CallObjectMethod(MessageDigestObj, MessageDigestClass_method_digest, x509CertificateObj_encoded); jbyteArray publicKeyArr = reinterpret_cast<jbyteArray>(publicKey); LOGI("getSign convert to 0x"); // 对获取的key进程16进制转换 int length = env->GetArrayLength(publicKeyArr); jbyte *bytes = env->GetByteArrayElements(publicKeyArr, 0); char *retValue = (char *) malloc(length * 3); int retValueIndex = 0; char tempHex[3]; for (int i = 0; i < length; i++) { char2Hex(bytes[i], tempHex); retValue[retValueIndex++] = tempHex[0]; retValue[retValueIndex++] = tempHex[1]; if (i < length - 1) { retValue[retValueIndex++] = ':'; } else { retValue[retValueIndex++] = 0; } } LOGI("getSign finish"); return retValue; }
Util.h
// // Created by wenlongbai on 8/14/17. // #ifndef BWL_UTIL_H #define BWL_UTIL_H #ifdef __cplusplus extern "C" { #endif #include "jni.h" #include "Constants.h" #include <android/log.h> #define LOG_TAG "tvlive_pwd" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #ifdef __DEBUG__ #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) #else #define LOGD(...) #endif // jstring转为char* char *jstring2cStr(JNIEnv *env, jstring jstr); // char*转为jstring jstring cStr2jstring(JNIEnv *env, const char *pat); // long转为char char *jlong2char(JNIEnv *env, jlong number); // char转为16进制 char *char2Hex(unsigned char c, char* hexValue) ; #ifdef __cplusplus }; #endif #endif //BWL_UTIL_H
Util.cpp
// // Created by wenlongbai on 8/14/17. // #include <malloc.h> #include <string.h> #include "jni.h" #include "Util.h" #define HEX_VALUES "0123456789ABCDEF" char *jstring2cStr(JNIEnv *env, jstring jstr) { const char *temp = (char *) env->GetStringUTFChars(jstr, NULL); char *ret = (char *) malloc(strlen(temp) + 1); strcpy(ret, temp); env->ReleaseStringUTFChars(jstr, temp); return ret; } jstring cStr2jstring(JNIEnv *env, const char *chars) { jstring ret = env->NewStringUTF(chars); return ret; } char *jlong2char(JNIEnv *env, jlong number) { char *chars = (char *) malloc(20); sprintf(chars, "%lld", number); return chars; } char *char2Hex(unsigned char c, char *hexValue) { if (c < 16) { hexValue[0] = HEX_VALUES[0]; hexValue[1] = HEX_VALUES[c]; } else { int l = c / 16; int r = c % 16; hexValue[0] = HEX_VALUES[l]; hexValue[1] = HEX_VALUES[r]; } hexValue[2] = 0; return hexValue; }