1. 获取包名

在Java代码中,可以通过以下方式获取当前应用的包名:

String packageName = getPackageName();

在JNI代码中,可以使用JNIEnv的GetObjectClass方法获取当前类的类对象,再使用GetMethodID方法获取包名方法的方法ID,最后调用CallObjectMethod方法获取包名字符串对象。具体代码如下:

jstring getPackageName(JNIEnv *env, jobject thiz) {
    jclass clazz = env->GetObjectClass(thiz);
    jmethodID methodID = env->GetMethodID(clazz, "getPackageName", "()Ljava/lang/String;");
    return (jstring) env->CallObjectMethod(thiz, methodID);
}
  1. 获取应用签名的MD5信息

在Java代码中,可以通过以下方式获取当前应用签名的MD5信息:

String md5 = getSignature("MD5");

其中getSignature方法的实现如下:

private String getSignature(String algorithm) {
    try {
        PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);
        byte[] signature = packageInfo.signatures[0].toByteArray();
        MessageDigest md = MessageDigest.getInstance(algorithm);
        byte[] digest = md.digest(signature);
        return bytesToHexString(digest);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

private String bytesToHexString(byte[] bytes) {
    StringBuilder sb = new StringBuilder();
    for (byte b : bytes) {
        String hex = Integer.toHexString(0xFF & b);
        if (hex.length() == 1) {
            sb.append('0');
        }
        sb.append(hex);
    }
    return sb.toString();
}

在JNI代码中,可以使用JNIEnv的GetObjectClass方法获取当前类的类对象,再使用GetMethodID方法获取应用签名方法的方法ID,最后调用CallObjectMethod方法获取签名字符串对象。具体代码如下:

jstring getSignature(JNIEnv *env, jobject thiz, jstring algorithm) {
    jclass contextClass = env->GetObjectClass(thiz);
    jclass packageManagerClass = env->FindClass("android/content/pm/PackageManager");
    jfieldID packageManagerFieldID = env->GetStaticFieldID(contextClass, "GET_SIGNATURES", "I");
    jint getSignatures = env->GetStaticIntField(contextClass, packageManagerFieldID);
    jmethodID getPackageManagerMethodID = env->GetMethodID(contextClass, "getPackageManager", "()Landroid/content/pm/PackageManager;");
    jobject packageManager = env->CallObjectMethod(thiz, getPackageManagerMethodID);
    jmethodID getPackageInfoMethodID = env->GetMethodID(packageManagerClass, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
    jstring packageName = getPackageName(env, thiz);
    jobject packageInfo = env->CallObjectMethod(packageManager, getPackageInfoMethodID, packageName, getSignatures);
    jclass signatureClass = env->FindClass("android/content/pm/Signature");
    jfieldID signaturesFieldID = env->GetFieldID(packageInfoClass, "signatures", "[Landroid/content/pm/Signature;");
    jobjectArray signatures = (jobjectArray) env->GetObjectField(packageInfo, signaturesFieldID);
    jobject signature = env->GetObjectArrayElement(signatures, 0);
    jmethodID toByteArrayMethodID = env->GetMethodID(signatureClass, "toByteArray", "()[B");
    jbyteArray signatureBytes = (jbyteArray) env->CallObjectMethod(signature, toByteArrayMethodID);
    jstring result = hash(env, signatureBytes, algorithm);
    env->DeleteLocalRef(packageName);
    env->DeleteLocalRef(packageInfo);
    env->DeleteLocalRef(signatures);
    env->DeleteLocalRef(signature);
    env->DeleteLocalRef(signatureBytes);
    return result;
}

其中,hash方法是计算MD5或SHA1值的通用方法,实现代码如下:

jstring hash(JNIEnv *env, jbyteArray data, jstring algorithm) {
    jsize size = env->GetArrayLength(data);
    jbyte *bytes = env->GetByteArrayElements(data, nullptr);
    const char *algorithmChars = env->GetStringUTFChars(algorithm, nullptr);
    const EVP_MD *md = EVP_get_digestbyname(algorithmChars);
    unsigned char digest[EVP_MAX_MD_SIZE];
    unsigned int digestLength;
    EVP_MD_CTX *mdCtx = EVP_MD_CTX_new();
    EVP_DigestInit_ex(mdCtx, md, nullptr);
    EVP_DigestUpdate(mdCtx, bytes, size);
    EVP_DigestFinal_ex(mdCtx, digest, &digestLength);
    EVP_MD_CTX_free(mdCtx);
    env->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
    env->ReleaseStringUTFChars(algorithm, algorithmChars);
    return bytesToHexString(env, digest, digestLength);
}

jstring bytesToHexString(JNIEnv *env, const unsigned char *bytes, int length) {
    char hex[length * 2 + 1];
    for (int i = 0; i < length; i++) {
        sprintf(&hex[i * 2], "%02x", bytes[i]);
    }
    hex[length * 2] = '\0';
    return env->NewStringUTF(hex);
}
  1. 获取应用签名的SHA1信息

在Java代码中,可以通过以下方式获取当前应用签名的SHA1信息:

String sha1 = getSignature("SHA1");

在JNI代码中,可以使用hash方法计算SHA1值,具体代码同上,只需将getSignature方法中的algorithm参数改为"SHA1"即可

android通过jni获得包名签名信息的MD5、SHA1信息

原文地址: https://www.cveoy.top/t/topic/cHyh 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录