title: Why does one apk got different signatures in jni between emulator and real device?
body: <p>I try to print signatures in jni, but the same apk got different values between emulator and real device.
    Does any one knows why this happens?</p>
  
  <p>Emulator Pixel 2:</p>
  
  <pre><code>2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, [
  2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 30
  2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, ffffff82
  2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
  2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, ffffffdd
  2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 30
  2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, ffffff82
  2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
  2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 46
  2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 2
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 30
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, d
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 6
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 9
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 2a
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, ffffff86
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 48
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, ffffff86
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, fffffff7
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, d
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 5
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 5
  2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, ]
  2019-07-16 22:38:10.727 2620-4374/my.package.name I/jnitest.cpp: JNI::checkSignature, appSignature [0x119], [.2.C35(B)649+0,C64*25D1060/7-566]
  </code></pre>
  
  <p>Real Device Huawei:</p>
  
  <pre><code>2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, [
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 30
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 82
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, dd
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 30
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 82
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 46
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 2
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 30
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, d
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 6
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 9
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 2a
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 86
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 48
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 86
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, f7
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, d
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 5
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 5
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, ]
  2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::checkSignature, appSignature [0x115], [E2EC358B9649B0CC64A25D1060F7D566]
  </code></pre>
  
  <p>java:</p>
  
  <pre><code>jstring loadSignature(JNIEnv *env, jobject context) {
  //    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::loadSignature");
  
      jclass cls = env-&gt;GetObjectClass(context);
      jmethodID mid = env-&gt;GetMethodID(cls, "getPackageManager",
                                       "()Landroid/content/pm/PackageManager;");
  
      jobject pm = env-&gt;CallObjectMethod(context, mid);
  
      mid = env-&gt;GetMethodID(cls, "getPackageName", "()Ljava/lang/String;");
      jstring packageName = (jstring) env-&gt;CallObjectMethod(context, mid);
  
      cls = env-&gt;GetObjectClass(pm);
      mid = env-&gt;GetMethodID(cls, "getPackageInfo",
                             "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
      jobject packageInfo = env-&gt;CallObjectMethod(pm, mid, packageName, 0x40); //GET_SIGNATURES = 64;
      cls = env-&gt;GetObjectClass(packageInfo);
      jfieldID fid = env-&gt;GetFieldID(cls, "signatures", "[Landroid/content/pm/Signature;");
      jobjectArray signatures = (jobjectArray) env-&gt;GetObjectField(packageInfo, fid);
      jobject signature = env-&gt;GetObjectArrayElement(signatures, 0);
  
      cls = env-&gt;GetObjectClass(signature);
      mid = env-&gt;GetMethodID(cls, "toByteArray", "()[B");
      jbyteArray signatureByteArray = (jbyteArray) env-&gt;CallObjectMethod(signature, mid);
  
      env -&gt; DeleteLocalRef(cls);
      env -&gt; DeleteLocalRef(pm);
      env -&gt; DeleteLocalRef(packageName);
      env -&gt; DeleteLocalRef(packageInfo);
      env -&gt; DeleteLocalRef(signatures);
      env -&gt; DeleteLocalRef(signature);
  
      {
          // debug signature
          __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::loadSignature, [");
          jboolean isCopy;
          jbyte *bytes = env-&gt;GetByteArrayElements(signatureByteArray, &amp;isCopy);
          char *chars = (char *) bytes;
          for (int i = 0; i &lt; strlen(chars); i++) {
              __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::loadSignature, %x", chars[i]);
          }
          __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::loadSignature, ]");
      }
  
  
      return jbyteArrayToMd5(env, signatureByteArray);
  }
  
  
  jboolean checkSignature(JNIEnv *env, jobject context) {
  //    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::checkSignature");
  
      jstring appSignature = loadSignature(env, context);
      const char *charAppSignature = env-&gt;GetStringUTFChars(appSignature, 0);
      __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::checkSignature, %4d, [%s]", strlen(charAppSignature), charAppSignature);
  ...
  </code></pre>
  
  <p>Update:</p>
  
  <pre><code>    2019-07-17 01:23:18.633 11560-13925/my.package.name I/jnitest.cpp: JNI::loadSignature, signaturesSize=1
  
      jsize signaturesSize = env-&gt;GetArrayLength(signatures);
          __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::loadSignature, signaturesSize=%d", signaturesSize);
  </code></pre>
  
  <p>Update:</p>
  
  <pre><code>jstring jbyteArrayToMd5(JNIEnv *env, jbyteArray source) {
      //__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::jbyteArrayToMd5");
  
      jclass classMessageDigest = env-&gt;FindClass("java/security/MessageDigest");
      jmethodID midGetInstance = env-&gt;GetStaticMethodID(classMessageDigest, "getInstance",
                                                        "(Ljava/lang/String;)Ljava/security/MessageDigest;");
      // MessageDigest object
      jobject objMessageDigest = env-&gt;CallStaticObjectMethod(classMessageDigest, midGetInstance,
                                                             env-&gt;NewStringUTF("md5"));
  
      jmethodID midUpdate = env-&gt;GetMethodID(classMessageDigest, "update", "([B)V");
      env-&gt;CallVoidMethod(objMessageDigest, midUpdate, source);
  
      jmethodID midDigest = env-&gt;GetMethodID(classMessageDigest, "digest", "()[B");
      jbyteArray objArraySign = (jbyteArray) env-&gt;CallObjectMethod(objMessageDigest, midDigest);
  
      jsize intArrayLength = env-&gt;GetArrayLength(objArraySign);
      jbyte *byte_array_elements = env-&gt;GetByteArrayElements(objArraySign, NULL);
      size_t length = (size_t) intArrayLength * 2 + 1;
      char *char_result = (char *) malloc(length);
      memset(char_result, 0, length);
  
      ByteToHexStr((const char *) byte_array_elements, char_result, intArrayLength);
      *(char_result + intArrayLength * 2) = '\0';
  
      jstring stringResult = env-&gt;NewStringUTF(char_result);
      // release
      env-&gt;ReleaseByteArrayElements(objArraySign, byte_array_elements, JNI_ABORT);
      free(char_result);
      env-&gt;DeleteLocalRef(classMessageDigest);
      env-&gt;DeleteLocalRef(objMessageDigest);
  
      return stringResult;
  }
  </code></pre>
  
  <p>UPDATE 2nd:</p>
  
  <pre><code>void ByteToHexStr(const char *source, char *dest, int sourceLen) {
      //__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::ByteToHexStr");
  
      short i;
      char highByte, lowByte;
  
      for (i = 0; i &lt; sourceLen; i++) {
          highByte = source[i] &gt;&gt; 4;
          lowByte = source[i] &amp; 0x0f;
          highByte += 0x30;
  
          if (highByte &gt; 0x39) {
              dest[i * 2] = highByte + 0x07;
          } else {
              dest[i * 2] = highByte;
          }
  
          lowByte += 0x30;
          if (lowByte &gt; 0x39) {
              dest[i * 2 + 1] = lowByte + 0x07;
          } else {
              dest[i * 2 + 1] = lowByte;
          }
      }
  }
  </code></pre>