├── .gitignore
├── README.md
├── app
├── .gitignore
├── CMakeLists.txt
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── aizuzi
│ │ └── verificationdemo
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── cpp
│ │ ├── native-lib.cpp
│ │ └── valid.cpp
│ ├── java
│ │ └── com
│ │ │ └── aizuzi
│ │ │ └── verificationdemo
│ │ │ └── MainActivity.java
│ └── res
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── aizuzi
│ └── verificationdemo
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle
└── wrapper
│ └── gradle-wrapper.jar
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SignatureVerificationDemo
2 | Android 使用jni校验应用签名sha1值,防止so文件逆向盗用
3 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # For more information about using CMake with Android Studio, read the
2 | # documentation: https://d.android.com/studio/projects/add-native-code.html
3 |
4 | # Sets the minimum version of CMake required to build the native library.
5 |
6 | cmake_minimum_required(VERSION 3.4.1)
7 |
8 | # Creates and names a library, sets it as either STATIC
9 | # or SHARED, and provides the relative paths to its source code.
10 | # You can define multiple libraries, and CMake builds them for you.
11 | # Gradle automatically packages shared libraries with your APK.
12 |
13 |
14 | add_library( # Sets the name of the library.
15 | native-lib
16 |
17 | # Sets the library as a shared library.
18 | SHARED
19 |
20 | # Provides a relative path to your source file(s).
21 | src/main/cpp/native-lib.cpp)
22 |
23 | # Searches for a specified prebuilt library and stores the path as a
24 | # variable. Because CMake includes system libraries in the search path by
25 | # default, you only need to specify the name of the public NDK library
26 | # you want to add. CMake verifies that the library exists before
27 | # completing its build.
28 |
29 | find_library( # Sets the name of the path variable.
30 | log-lib
31 |
32 | # Specifies the name of the NDK library that
33 | # you want CMake to locate.
34 | log )
35 |
36 | # Specifies libraries CMake should link to your target library. You
37 | # can link multiple libraries, such as libraries you define in this
38 | # build script, prebuilt third-party libraries, or system libraries.
39 |
40 | target_link_libraries( # Specifies the target library.
41 | native-lib
42 |
43 | # Links the target library to the log library
44 | # included in the NDK.
45 | ${log-lib} )
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "25.0.2"
6 | defaultConfig {
7 | applicationId "com.aizuzi.verificationdemo"
8 | minSdkVersion 15
9 | targetSdkVersion 25
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | externalNativeBuild {
14 | cmake {
15 | cppFlags ""
16 | }
17 | }
18 | }
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 | externalNativeBuild {
26 | cmake {
27 | path "CMakeLists.txt"
28 | }
29 | }
30 | }
31 |
32 | dependencies {
33 | compile fileTree(dir: 'libs', include: ['*.jar'])
34 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
35 | exclude group: 'com.android.support', module: 'support-annotations'
36 | })
37 | compile 'com.android.support:appcompat-v7:25.3.1'
38 | compile 'com.android.support.constraint:constraint-layout:1.0.2'
39 | testCompile 'junit:junit:4.12'
40 | }
41 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/admin/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/aizuzi/verificationdemo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.aizuzi.verificationdemo;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.aizuzi.verificationdemo", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/cpp/native-lib.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include"valid.cpp"
4 |
5 | extern "C"
6 | JNIEXPORT jstring JNICALL
7 | Java_com_aizuzi_verificationdemo_MainActivity_getSignaturesSha1(
8 | JNIEnv *env,
9 | jobject,
10 | jobject contextObject) {
11 |
12 | return env->NewStringUTF(app_sha1);
13 | }
14 | extern "C"
15 | JNIEXPORT jboolean JNICALL
16 | Java_com_aizuzi_verificationdemo_MainActivity_checkSha1(
17 | JNIEnv *env,
18 | jobject,
19 | jobject contextObject) {
20 |
21 | char *sha1 = getSha1(env,contextObject);
22 |
23 | jboolean result = checkValidity(env,sha1);
24 |
25 | return result;
26 | }
27 | extern "C"
28 | JNIEXPORT jstring JNICALL
29 | Java_com_aizuzi_verificationdemo_MainActivity_getToken(
30 | JNIEnv *env,
31 | jobject,
32 | jobject contextObject,
33 | jstring userId) {
34 | char *sha1 = getSha1(env,contextObject);
35 | jboolean result = checkValidity(env,sha1);
36 |
37 | if(result){
38 | return env->NewStringUTF("获取Token成功");
39 | }else{
40 | return env->NewStringUTF("获取失败,请检查valid.cpp文件配置的sha1值");
41 | }
42 | }
--------------------------------------------------------------------------------
/app/src/main/cpp/valid.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #define TAG "jni-log"
7 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__)
8 |
9 | //签名信息
10 | const char *app_sha1="81BA0CF9134C6415F34C3BCC854913A53C71415E";
11 | const char hexcode[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
12 |
13 | char* getSha1(JNIEnv *env, jobject context_object){
14 | //上下文对象
15 | jclass context_class = env->GetObjectClass(context_object);
16 |
17 | //反射获取PackageManager
18 | jmethodID methodId = env->GetMethodID(context_class, "getPackageManager", "()Landroid/content/pm/PackageManager;");
19 | jobject package_manager = env->CallObjectMethod(context_object, methodId);
20 | if (package_manager == NULL) {
21 | LOGD("package_manager is NULL!!!");
22 | return NULL;
23 | }
24 |
25 | //反射获取包名
26 | methodId = env->GetMethodID(context_class, "getPackageName", "()Ljava/lang/String;");
27 | jstring package_name = (jstring)env->CallObjectMethod(context_object, methodId);
28 | if (package_name == NULL) {
29 | LOGD("package_name is NULL!!!");
30 | return NULL;
31 | }
32 | env->DeleteLocalRef(context_class);
33 |
34 | //获取PackageInfo对象
35 | jclass pack_manager_class = env->GetObjectClass(package_manager);
36 | methodId = env->GetMethodID(pack_manager_class, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
37 | env->DeleteLocalRef(pack_manager_class);
38 | jobject package_info = env->CallObjectMethod(package_manager, methodId, package_name, 0x40);
39 | if (package_info == NULL) {
40 | LOGD("getPackageInfo() is NULL!!!");
41 | return NULL;
42 | }
43 | env->DeleteLocalRef(package_manager);
44 |
45 | //获取签名信息
46 | jclass package_info_class = env->GetObjectClass(package_info);
47 | jfieldID fieldId = env->GetFieldID(package_info_class, "signatures", "[Landroid/content/pm/Signature;");
48 | env->DeleteLocalRef(package_info_class);
49 | jobjectArray signature_object_array = (jobjectArray)env->GetObjectField(package_info, fieldId);
50 | if (signature_object_array == NULL) {
51 | LOGD("signature is NULL!!!");
52 | return NULL;
53 | }
54 | jobject signature_object = env->GetObjectArrayElement(signature_object_array, 0);
55 | env->DeleteLocalRef(package_info);
56 |
57 | //签名信息转换成sha1值
58 | jclass signature_class = env->GetObjectClass(signature_object);
59 | methodId = env->GetMethodID(signature_class, "toByteArray", "()[B");
60 | env->DeleteLocalRef(signature_class);
61 | jbyteArray signature_byte = (jbyteArray) env->CallObjectMethod(signature_object, methodId);
62 | jclass byte_array_input_class=env->FindClass("java/io/ByteArrayInputStream");
63 | methodId=env->GetMethodID(byte_array_input_class,"","([B)V");
64 | jobject byte_array_input=env->NewObject(byte_array_input_class,methodId,signature_byte);
65 | jclass certificate_factory_class=env->FindClass("java/security/cert/CertificateFactory");
66 | methodId=env->GetStaticMethodID(certificate_factory_class,"getInstance","(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;");
67 | jstring x_509_jstring=env->NewStringUTF("X.509");
68 | jobject cert_factory=env->CallStaticObjectMethod(certificate_factory_class,methodId,x_509_jstring);
69 | methodId=env->GetMethodID(certificate_factory_class,"generateCertificate",("(Ljava/io/InputStream;)Ljava/security/cert/Certificate;"));
70 | jobject x509_cert=env->CallObjectMethod(cert_factory,methodId,byte_array_input);
71 | env->DeleteLocalRef(certificate_factory_class);
72 | jclass x509_cert_class=env->GetObjectClass(x509_cert);
73 | methodId=env->GetMethodID(x509_cert_class,"getEncoded","()[B");
74 | jbyteArray cert_byte=(jbyteArray)env->CallObjectMethod(x509_cert,methodId);
75 | env->DeleteLocalRef(x509_cert_class);
76 | jclass message_digest_class=env->FindClass("java/security/MessageDigest");
77 | methodId=env->GetStaticMethodID(message_digest_class,"getInstance","(Ljava/lang/String;)Ljava/security/MessageDigest;");
78 | jstring sha1_jstring=env->NewStringUTF("SHA1");
79 | jobject sha1_digest=env->CallStaticObjectMethod(message_digest_class,methodId,sha1_jstring);
80 | methodId=env->GetMethodID(message_digest_class,"digest","([B)[B");
81 | jbyteArray sha1_byte=(jbyteArray)env->CallObjectMethod(sha1_digest,methodId,cert_byte);
82 | env->DeleteLocalRef(message_digest_class);
83 |
84 | //转换成char
85 | jsize array_size=env->GetArrayLength(sha1_byte);
86 | jbyte* sha1 =env->GetByteArrayElements(sha1_byte,NULL);
87 | char *hex_sha=new char[array_size*2+1];
88 | for (int i = 0; i
2 |
11 |
12 |
16 |
17 |
21 |
22 |
26 |
27 |
28 |
33 |
34 |
38 |
39 |
43 |
44 |
45 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aizuzi/SignatureVerificationDemo/179c851028cc392ce05b4d9f479f6c22df1c0f0e/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aizuzi/SignatureVerificationDemo/179c851028cc392ce05b4d9f479f6c22df1c0f0e/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aizuzi/SignatureVerificationDemo/179c851028cc392ce05b4d9f479f6c22df1c0f0e/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aizuzi/SignatureVerificationDemo/179c851028cc392ce05b4d9f479f6c22df1c0f0e/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aizuzi/SignatureVerificationDemo/179c851028cc392ce05b4d9f479f6c22df1c0f0e/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aizuzi/SignatureVerificationDemo/179c851028cc392ce05b4d9f479f6c22df1c0f0e/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aizuzi/SignatureVerificationDemo/179c851028cc392ce05b4d9f479f6c22df1c0f0e/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aizuzi/SignatureVerificationDemo/179c851028cc392ce05b4d9f479f6c22df1c0f0e/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aizuzi/SignatureVerificationDemo/179c851028cc392ce05b4d9f479f6c22df1c0f0e/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aizuzi/SignatureVerificationDemo/179c851028cc392ce05b4d9f479f6c22df1c0f0e/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | SignatureVerificationDemo
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/aizuzi/verificationdemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.aizuzi.verificationdemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.3.3'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aizuzi/SignatureVerificationDemo/179c851028cc392ce05b4d9f479f6c22df1c0f0e/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------