2017-07-28 62 views
1

我試圖在運行時使用簽名證書生成令牌,並在服務器上驗證該令牌以訪問任何資源。我不想令牌存儲在XML文件,因爲它是生成令牌APK爲訪問服務器資源生成令牌

代碼的逆向工程後可爲

public String getToken() { 
    Signature[] sigs; 
    try { 
     sigs = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures; 

     String token = sigs[0].toCharsString(); 
     return token; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 

的問題是,即使APK是來自同一所產生的一些裝置回不同的令牌證書,不知道它爲什麼爲某些設備返回不同令牌的原因。

我想要的是生成一個令牌,可以用來訪問網絡資源,我不想在apk中存儲令牌沒有人可以通過反編譯apk獲得令牌。

+0

_some設備返回不同的令牌_所以你說有一些設備給你相同的令牌? – SripadRaj

+0

我們在服務器上添加了日誌文件,主要設備返回相同的令牌,但其中一些返回不同的令牌(1%的用戶返回不同的令牌)。 –

+0

regid = FirebaseInstanceId.getInstance()。getToken();像這樣得到 –

回答

1

可以存儲與C或C++ 令牌,並添加簽名驗證

public static String getSignature(Context context) { 
try { 
    PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES); 
    Signature[] signatures = packageInfo.signatures; 
    return signatures[0].toCharsString(); 
} catch(PackageManager.NameNotFoundException e) { 
    e.printStackTrace(); 
} 
return null; 

}

const char * app_signature = "singsing"; 
static int is_valid = 0; 
void 
Java_com_xxx_xxx_nativeInit(JNIEnv *env, jobject thiz, jobject context_object){ 
    jclass context_class = (*env)->GetObjectClass(env, context_object); 

    //context.getPackageManager() 
    jmethodID methodId = (*env)->GetMethodID(env, context_class, "getPackageManager", "()Landroid/content/pm/PackageManager;"); 
    jobject package_manager_object = (*env)->CallObjectMethod(env, context_object, methodId); 
    if (package_manager_object == NULL) { 
     return; 
    } 

    //context.getPackageName() 
    methodId = (*env)->GetMethodID(env, context_class, "getPackageName", "()Ljava/lang/String;"); 
    jstring package_name_string = (jstring)(*env)->CallObjectMethod(env, context_object, methodId); 
    if (package_name_string == NULL) { 
     return ; 
    } 
    (*env)->DeleteLocalRef(env,context_class); 

    //PackageManager.getPackageInfo(Sting, int) 
    //public static final int GET_SIGNATURES= 0x00000040; 
    jclass pack_manager_class = (*env)->GetObjectClass(env, package_manager_object); 
    methodId = (*env)->GetMethodID(env, pack_manager_class, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); 
    (*env)->DeleteLocalRef(env,pack_manager_class); 
    jobject package_info_object = (*env)->CallObjectMethod(env, package_manager_object, methodId, package_name_string, 0x40); 
    if (package_info_object == NULL) { 
     return ; 
    } 
    (*env)->DeleteLocalRef(env,package_manager_object); 

    //PackageInfo.signatures[0] 
    jclass package_info_class = (*env)->GetObjectClass(env, package_info_object); 
    jfieldID fieldId = (*env)->GetFieldID(env, package_info_class, "signatures", "[Landroid/content/pm/Signature;"); 
    (*env)->DeleteLocalRef(env,package_info_class); 
    jobjectArray signature_object_array = (jobjectArray)(*env)->GetObjectField(env,package_info_object, fieldId); 
    if (signature_object_array == NULL) { 
     return ; 
    } 
    jobject signature_object = (*env)->GetObjectArrayElement(env,signature_object_array, 0); 
    (*env)->DeleteLocalRef(env,package_info_object); 
    jclass signature_class = (*env)->GetObjectClass(env, signature_object); 
    methodId = (*env)->GetMethodID(env, signature_class, "toCharsString", "()Ljava/lang/String;"); 
    (*env)->DeleteLocalRef(env,signature_class); 
    jstring signature_jstirng = (jstring) (*env)->CallObjectMethod(env, signature_object, methodId); 
    const char *sign=(*env)->GetStringUTFChars(env, signature_jstirng,NULL); 
    if (strcmp(sign,app_signature)==0 || strcmp(sign,app_j_s)==0) { 
     is_valid= 1; 
    } 
    return; 
} 
+0

有錯誤無法解析'GetObjectClass(contextObject)',請問您可以提供**。c **文件 –

+0

是他們用同樣的函數加密'c_msg'的方法嗎? –

+0

@OmInfowaveDevelopers我用c更新了。 – sanemars

1

簽名證書的指紋在所有設備中都是唯一的。您是否可以嘗試使用此解決方案將該指紋作爲字符串獲取並將其用作標記。

https://stackoverflow.com/a/22506133/4586742

+0

我的代碼有什麼問題?我已經添加了一些設備調用Web服務的日誌文件不同的令牌。 –

+0

所以它是可以破解的,任何人都可以使用上述邏輯生成**指紋**,並使用該密鑰訪問resources.is他們的任何解決方案。 –

+0

t也可以使用某種技術生成指紋'列表 apps = context.getPackageManager()。getInstalledPackages(PackageMana ger.GET_SIGNATURES);'給出(Signature s:pi.signatures){Log.d(「PackageTrackerfix」,「old:」+ s.toCharsString()+「」+ s)的已安裝軟件包的所有列表。的hashCode()); }'它返回'generateCertificate()'中使用的所有證書詳細信息' –

0

@Om Infowave開發商,

我建議你使用Android Keystore System 生成KeyPair然後使用KeyPair加密令牌,將令牌存儲在共享首選項中。無論何時需要使用KeyPair的令牌解密令牌。

  1. 這樣你每次都得到唯一的令牌。
  2. 令牌被加密和保護。
  3. KeyPair因每個設備而異,因此更安全。

另外我只注意到你正在返回基於零索引的密鑰。他們可能是你在隨後的指數中尋找關鍵的機會。建議您記錄存儲在Signature[] sigs中的所有密鑰;

希望得到這個幫助。

+0

@桑代如何驗證服務器上的這個令牌? –

+0

您目前如何驗證服務器上的令牌?使用目前在服務器上驗證令牌的相同方式。唯一的區別是您在第一次生成後以加密格式在Android設備上以共享首選項的形式存儲了令牌。之後從共享首選項解密令牌中提取令牌並將其發送到服務器。如果你有任何其他幫助,請告訴我。非常樂意幫助。 – Sandy

+0

另一種方法是將設備ID和令牌發送到服務器,將設備ID和令牌存儲在服務器上。 – Sandy

相關問題