使用jni技術進行android應用簽名資訊核查及敏感資訊保護

來源:互聯網
上載者:User

標籤:android   jni   反編譯   簽名資訊   

       最近業餘時間寫了一款應用《搖啊搖》,安智、安卓、360等幾個市集已經陸續審核通過並上線。從有想法到最終將產品做出來並發布,斷斷續續花了近二個半月的業餘時間,總體來講還算順利,雖然期間也遇到幾個小技術痛點,最後解決的還算滿意。今天說下其中一個小技術痛點,現在想想這個小技術痛點也很平常,但還是分享出來,希望對有相同疑惑的同學有協助。       因為java語言自身特性的原因,導致android程式很容易被反編譯,雖然可以採用代碼混淆的方式,但是如果用了第三方庫,混淆腳步編寫不好,代碼混淆後又會出現程式運行不穩定問題。而沒有混淆的程式一旦被反編譯後,源碼中大量的敏感資訊將會暴露無遺。比如與伺服器互動的url地址資訊,如果使用了動態連結程式庫,那麼native方法也將暴露,況且混淆時是不混淆native方法的。別人看到native方法,就可以自己載入so檔案,那麼很多核心的東西,別人就可以間接的使用了,雖然他不一定能用好,但至少可以調用了。針對上面的林林總總程式被反編譯後可能出現的問題,我的解決方案是使用jni技術,在ndk環境下做包簽名資訊核查,由於是ndk環境,所以這個很難反編譯,也很難繞過該核查。理論上,簽名檔案keystore是唯一的,並且只有程式作者才擁有。具體做法為,在所有的native方法內,增加簽名資訊核查判斷,只有簽名資訊核查通過,程式才能做進一步操作,否則直接返回NULL,這樣,即使別人拿到了so檔案,摸清楚了native方法參數及用法,但由於簽名資訊不一致,native方法全部返回NULL,so檔案瞬間變成磚頭。同樣,對於url地址等敏感資訊,增加簽名資訊核查,只有核查通過,程式才會返回正確的字串,否則直接返回NULL,這樣可以很好的隱藏和保護敏感資訊。說了半天,關鍵的一步是如何在ndk環境下,擷取包簽名資訊,下面的代碼為相關實現。
jstring loadSignature(JNIEnv* env, jobject obj){// 獲得Context類    jclass cls = (*env)->GetObjectClass(env, obj);    // 得到getPackageManager方法的ID    jmethodID mid = (*env)->GetMethodID(env, cls, "getPackageManager", "()Landroid/content/pm/PackageManager;");    // 獲得應用程式套件的管理器    jobject pm = (*env)->CallObjectMethod(env, obj, mid);    // 得到getPackageName方法的ID    mid = (*env)->GetMethodID(env, cls, "getPackageName", "()Ljava/lang/String;");    // 獲得當前應用程式套件名    jstring packageName = (jstring)(*env)->CallObjectMethod(env, obj, mid);    // 獲得PackageManager類    cls = (*env)->GetObjectClass(env, pm);    // 得到getPackageInfo方法的ID    mid  = (*env)->GetMethodID(env, cls, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");    // 獲得應用程式套件的資訊    jobject packageInfo = (*env)->CallObjectMethod(env, pm, mid, packageName, 0x40); //GET_SIGNATURES = 64;    // 獲得PackageInfo 類    cls = (*env)->GetObjectClass(env, packageInfo);    // 獲得簽名數組屬性的ID    jfieldID fid = (*env)->GetFieldID(env, cls, "signatures", "[Landroid/content/pm/Signature;");    // 得到簽名數組    jobjectArray signatures = (jobjectArray)(*env)->GetObjectField(env, packageInfo, fid);    // 得到簽名    jobject sign = (*env)->GetObjectArrayElement(env, signatures, 0);    // 獲得Signature類    cls = (*env)->GetObjectClass(env, sign);    // 得到toCharsString方法的ID    mid = (*env)->GetMethodID(env, cls, "toCharsString", "()Ljava/lang/String;");    // 返回當前應用簽名資訊    return (jstring)(*env)->CallObjectMethod(env, sign, mid);}
       上述代碼獲得的包簽名資訊實際是一個很長的字串,為了更高效的進行簽名資訊比對,還可以將其進行md5加密,加密成32位字串形式。另外,我在查閱資料過程中,看到有的資料提到用包簽名的hashcode值做比對,這種方式更簡單一點,但我沒有採用這種方式,總覺得這種方式可能不精確,僅僅是個人覺得,有興趣的同學可以查閱更多相關資料。這裡還要說明一點,上面代碼獲得的包簽名字串資訊,使用md5加密後,得到的加密結果與包簽名實際的md5 fingerprint是不一致的。主要是因為將簽名資訊使用toCharsString()轉換成字串後在進行md5加密所致,如果使用toByteArray()將其轉成數組,然後加密,加密結果與包簽名實際md5 fingerprint將是一致的。

使用jni技術進行android應用簽名資訊核查及敏感資訊保護

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.