рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдмрддрд╛рдПрдВрдЧреЗ рдХрд┐ рдХреИрд╕реЗ рдЖрдк Google рд╕реЗ рдорд╛рдирдХ рд╕рдорд╛рдзрд╛рди рдХреЛ рдПрдХреАрдХреГрдд рдХрд┐рдП рдмрд┐рдирд╛ рдЕрдкрдиреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рд╣реИрдХ рд╣реЛрдиреЗ рд╕реЗ рдмрдЪрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХрд╛рд░реНрдп рдХреЛрдб рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ? рд╣рдо рдХрдЯреМрддреА рдХреЗ рд▓рд┐рдП рдкреВрдЫреЗрдВ!
Google рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд▓рд╛рдЗрд╕реЗрдВрд╕рд┐рдВрдЧ рдХреА рдХрдордЬреЛрд░реА рдХреНрдпрд╛ рд╣реИ?
рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рддрдВрддреНрд░ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреА рд╣реИрдХрд┐рдВрдЧ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИред рдЖрдкрдХреЛ рдмрд╕ рдПрдкреАрдХреЗрдЯреВрд▓ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдирд╛ рд╣реИ, рд▓рд╛рдЗрд╕реЗрдВрд╕рдЪреЗрдпрд░ рдХреНрд▓рд╛рд╕ рдвреВрдВрдврдирд╛ рд╣реИ рдФрд░ рдЪреЗрдХрдЕрдЯреИрдХ рд╡рд┐рдзрд┐ рдХреЛ рдереЛрдбрд╝рд╛ рдореЛрдбрд╝рдирд╛ рд╣реИред
рдЕрдкрдиреА рдЦреБрдж рдХреА рд╕реБрд░рдХреНрд╖рд╛ рдХрд╛ рдПрд╣рд╕рд╛рд╕ рдХреИрд╕реЗ рдХрд░реЗрдВ?
рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдХрд┐рд╕реА рднреА рд░рдХреНрд╖рд╛ рдХреЛ рддреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рд╡рд┐рдзрд┐ рдПрдХ рдЪрд╛рдВрджреА рдХреА рдЧреЛрд▓реА рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЬреАрд╡рди рдХрд╛ рдЕрдзрд┐рдХрд╛рд░ рд╣реИред рдЖрд╡реЗрджрди рдХреА рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛ рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЙрд╕ рдкреНрд░рдорд╛рдгрдкрддреНрд░ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдЗрд╕ рдЖрд╡реЗрджрди рдкрд░ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд┐рдП рдЧрдП рдереЗред рдкреНрд░рдорд╛рдгрдкрддреНрд░ рдЬрд╛рдирдХрд╛рд░реА рдкреИрдХреЗрдЬрдЗрдиреНрдлреЛ рд╕реЗ рдкрдврд╝реА рдЬрд╛ рд╕рдХрддреА рд╣реИ:
PackageInfo info =getPackageManager().getPackageInfo(getPackageName(), 0); Signature[] signatures = info.signatures;
рд╕рд░рдгреА рдХреЗ рд╢реВрдиреНрдп рддрддреНрд╡ рдореЗрдВ рдЙрд╕ рдХреБрдВрдЬреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рд╣реЛрдЧреА рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдЖрд╡реЗрджрди рдкрд░ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд┐рдП рдЧрдП рдереЗред рдХреБрдВрдЬреА рдХреЛ рд╕реНрд╡рдпрдВ рд╕рд╣реЗрдЬреЗрдВ, рдЖрдкрдХреЛ рдмрд╣реБрдд рдЬрд▓реНрдж рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред
рдпрд╣ рддрд░реНрдХрд╕рдВрдЧрдд рд╣реИ рдХрд┐ рдЬрд╛рд╡рд╛ рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдПрдкреАрдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдПрдХ рд╕рдорд╛рди рддрдХрдиреАрдХ рдХреБрдЫ рд╣реА рдорд┐рдирдЯреЛрдВ рдореЗрдВ рдЖрдкрдХреА рд╕реБрд░рдХреНрд╖рд╛ рдХреЛ рджрдлрди рдХрд░ рджреЗрдЧреАред рдЗрд╕рд▓рд┐рдП, рдЗрд╕ рдЪреЗрдХ рдХреЛ рд╕рдХреНрд░рд┐рдп рд╕реНрддрд░ рдкрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
const char* rsa = "PUT_YOUR_RSA_KEY_HERE"; jint verifyCertificate(JNIEnv *env, jobject obj, jobject cnt) { jclass cls = env->GetObjectClass(cnt); jmethodID mid = env->GetMethodID(cls, "getPackageManager", "()Landroid/content/pm/PackageManager;"); jmethodID pnid = env->GetMethodID(cls, "getPackageName", "()Ljava/lang/String;"); if (mid == 0 || pnid == 0) { return ERROR; } jobject pacMan_o = env->CallObjectMethod(cnt, mid); jclass pacMan = env->GetObjectClass(pacMan_o); jstring packName = (jstring) env->CallObjectMethod(cnt, pnid); int flags = 0x40; mid = env->GetMethodID(pacMan, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); if (mid == 0) { return ERROR; } jobject pack_inf_o = (jobject) env->CallObjectMethod(pacMan_o, mid, packName, flags); jclass packinf = env->GetObjectClass(pack_inf_o); jfieldID fid; fid = env->GetFieldID(packinf, "signatures", "[Landroid/content/pm/Signature;"); jobjectArray signatures = (jobjectArray) env->GetObjectField(pack_inf_o, fid); jobject signature0 = env->GetObjectArrayElement(signatures, 0); mid = env->GetMethodID(env->GetObjectClass(signature0), "toByteArray", "()[B"); jbyteArray cert = (jbyteArray) env->CallObjectMethod(signature0, mid); if (cert == 0) { return ERROR; } jclass BAIS = env->FindClass("java/io/ByteArrayInputStream"); if (BAIS == 0) { return ERROR; } mid = env->GetMethodID(BAIS, "<init>", "([B)V"); if (mid == 0) { return ERROR; } jobject input = env->NewObject(BAIS, mid, cert); jclass CF = env->FindClass("java/security/cert/CertificateFactory"); mid = env->GetStaticMethodID(CF, "getInstance", "(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;"); jstring X509 = env->NewStringUTF("X509"); jobject cf = env->CallStaticObjectMethod(CF, mid, X509); if (cf == 0) { return ERROR; }
рдЖрдЧреЗ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ?
рдЗрд╕рдХреА рдХреБрдЫ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдЙрд╕реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рдФрд░ рдореВрд▓реНрдп рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдкреНрд░рд╛рдорд╛рдгрд┐рдХрддрд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рдорд╛рдг рдкрддреНрд░ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдФрд░ рдлрдВрддрд╛рд╕реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдордд рднреВрд▓рдирд╛, рдЬреЛ рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рд╣реИрдХрд░ рдХреЛ рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдк рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдЖрд╡реЗрджрди рдХреА рдпрд╣ рдкреНрд░рддрд┐ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдирд╣реАрдВ рд╣реИред рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдмрд╛рдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рддрддреНрд╡ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рдордЬреЗрджрд╛рд░ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдЦреЗрд▓ рд╣реИ, рддреЛ рдЖрдк рдЕрдкрдиреЗ рд╡рд┐рд░реЛрдзрд┐рдпреЛрдВ рдХреЛ рддрд╛рдХрдд рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЛ рдЕрдзрд┐рдХ рдХрдордЬреЛрд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк 10% рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдмреВрдБрджреЗрдВ рднреА рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ (zabayevskiy
habrayuzer рд╕реЗ рдПрдХ рдирд┐рд╖реНрдкрдХреНрд╖ рдЯрд┐рдкреНрдкрдгреА: рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдмреВрдБрджреЗрдВ рдЖрдкрдХреЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдХрд░реНрдо рдХреЛ рдмрд░реНрдмрд╛рдж рдХрд░ рджреЗрдВрдЧреАред)ред рдпрд╣ рд╕рдм рдЖрдк рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред
рдпрд╣рд╛рдБ рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╣реИ:
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рд╡рд░реНрдЧ рд▓рд┐рдЦреЗрдВ рдЬреЛ рдХреБрдЫ рдбреЗрдЯрд╛ рдХреЛ рдкреБрдирдГ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред
public class YourClass { static { System.loadLibrary("name_of_library"); } public native int getSomeValue(); public native void init(Context ctx); }
рд╣рд░ рдмрд╛рд░ рдкреНрд░рдорд╛рдгрдкрддреНрд░ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдХреЛ рд▓рд╛рдЧреВ рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП init рд╡рд┐рдзрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рджреЗрд╢реА рддрд░реАрдХреЛрдВ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди:
jint isCertCorrect = 0; JNIEXPORT void JNICALL Java_com_your_package_YourClass_init(JNIEnv *env, jobject obj, jobject ctx) { isCertCorrect = verifyCertificate(env, obj, ctx); } JNIEXPORT jint JNICALL Java_com_your_package_YourClass_getSomeValue(JNIEnv *env, jobject obj) { if (isCertCorrect ) {
рдЗрд╕ рд╕реБрд░рдХреНрд╖рд╛ рд╡рд┐рдХрд▓реНрдк рдХреЛ рдЕрд╕рд╣рдорддрд┐ рд╕реЗ рднреА рд╣реИрдХ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд▓рд┐рдП рдЬрд╛рд╡рд╛ рд╕реНрддрд░ рдкрд░ рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЬреНрдЮрд╛рди рдХреА рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рд╕реНрддрд░ рдФрд░ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рдордп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреБрдЫ рдирд┐рд╢реНрдЪрд┐рдд рд╕рд╛рдзрди рд╣реИрдВ, рддреЛ рдпрд╣ рд╕реА рдХреЛрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдУрдлрд╝реНрдлрд╝рд╕рдХреЗрдЯрд░ рдЦрд░реАрджрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдЬрд┐рд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реИрдХрд┐рдВрдЧ рдПрдХ рддреБрдЪреНрдЫ рдХрд╛рд░реНрдп рд╕реЗ рджреВрд░ рд╣реЛрдЧреАред
рдПрдХ рд╕рд░реНрд╡рд░ рднрд╛рдЧ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЖрд╡реЗрджрди рд╕рдВрд░рдХреНрд╖рдгред
рдпрджрд┐ рд╕рд░реНрд╡рд░ рдкрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдЬрд┐рдХ рдХрд╛ рднрд╛рдЧ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╕рд░реНрд╡рд░ рдХреЛ рдкреНрд░рдорд╛рдгрдкрддреНрд░ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдЬрд╛рд░реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ, рдЖрдк рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
- рд╕рд░реНрд╡рд░ рдирд┐рдЬреА рдФрд░ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдЖрд░рдПрд╕рдП рдХреБрдВрдЬреА рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ;
- рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд░реНрд╡рд░ рдХреЛ рдПрдХ рдЕрдиреБрд░реЛрдз рднреЗрдЬрддрд╛ рд╣реИ рдФрд░ рдПрдХ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХреБрдВрдЬреА рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ;
- рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд░, рд╣рдо рдореВрд▓ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдлреЙрд░реНрдо рдХреЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реНрдЯреНрд░рд┐рдВрдЧрдЗрдирдЗрдиреНрдлреЛ (рд╕реНрдЯреНрд░рд┐рдВрдЧ publicKey) рдХреЗ рд╕рд╛рде рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ; рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреНрд░рдорд╛рдгрдкрддреНрд░ рдкрдврд╝рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕рдореЗрдВ рдХреБрдЫ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЪрд░ рдЬреЛрдбрд╝реЗрдВ, рдлрд┐рд░ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдЖрд░рдПрд╕рдП рдХреБрдВрдЬреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдХрд░реЗрдВ;
- рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд░реНрд╡рд░ рдХреЛ рдПрдХ рдирдпрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИ, рдкреНрд░рд╛рдкреНрдд рд╕реНрдЯреНрд░рд┐рдВрдЧ рднреЗрдЬ рд░рд╣рд╛ рд╣реИред рд╕рд░реНрд╡рд░ рдбрд┐рдХреЛрдбрд┐рдВрдЧ рдХрд░рддрд╛ рд╣реИ, рдкреНрд░рдорд╛рдг рдкрддреНрд░ рдХреЛ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЪрд░ рд╕реЗ рдЕрд▓рдЧ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреА рдкреНрд░рд╛рдорд╛рдгрд┐рдХрддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ;
- рд╕реНрдХреИрди рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╕рд░реНрд╡рд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рднреА рдХреНрд▓рд╛рдЗрдВрдЯ рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рдЬрд╡рд╛рдм рджреЗрддрд╛ рд╣реИред
рд╣рдореЗрдВ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рддрдВрддреНрд░ Habr рдХреЗ рдкрд╛рдардХреЛрдВ рдХреЛ рдЕрдкрдиреЗ Android рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рд╕реЗ рдЖрдп рдмрдврд╝рд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред