我不确定这个答案有多准确,但仍然发布它,因为我想从 Android 极客那里得到一些回应
考虑到 C 代码难以反编译,我使用 Android NDK 编写了一个简单的原生 C 库(.so),其中包含生成密码的算法。仅当应用程序由我的证书签名时才会执行该算法。如果有人在任何其他应用程序中重新使用此库,它不会返回密码,因为证书不匹配。我从这篇文章中得到了这个想法:http:
//digital-identity.dk/2010/12/protecting-ip-in-android-applications/
这就是我获得证书的方式:
void Java_dk_digitalidetity_android_SomeClass_SomeMethod(JNIEnv* env, jobject obj) {
// this.getPackageManager()
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID mid = (*env)->GetMethodID(env, cls, "getPackageManager", "()Landroid/content/pm/PackageManager;");
jobject packageManager = (*env)->CallObjectMethod(env, obj, mid);
// this.getPackageName()
mid = (*env)->GetMethodID(env, cls, "getPackageName", "()Ljava/lang/String;");
jstring packageName = (jstring) (*env)->CallObjectMethod(env, obj, mid);
// packageManager->getPackageInfo(packageName, GET_SIGNATURES);
cls = (*env)->GetObjectClass(env, packageManager);
mid = (*env)->GetMethodID(env, cls, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
jint flags = GET_SIGNATURES;
jobject packageInfo = (*env)->CallObjectMethod(env, packageManager, mid, packageName, flags);
// packageInfo->signatures
cls = (*env)->GetObjectClass(env, packageInfo);
jfieldID fid = (*env)->GetFieldID(env, cls, "signatures", "[Landroid/content/pm/Signature;");
jobject signatures = (*env)->GetObjectField(env, packageInfo, fid);
// signatures[0]
jobject signature = (*env)->GetObjectArrayElement(env, signatures, 0);
// signature->toByteArray()
cls = (*env)->GetObjectClass(env, signature);
mid = (*env)->GetMethodID(env, cls, "toByteArray", "()[B");
jbytearray certificate = (*env)->CallObjectMethod(env, signature, mid);
}