Android安全之應用簽名驗證

Android安全之應用簽名驗證

有時我們需要確保一個應用就是我們想要啓動的那個應用,從而確保應用間通信的安全。這話聽起來有點繞,下面以一個具體的例子來說明。


假如一家公司A做了一個支付應用PayApp,包名是”com.testa.pay”。隨着這個支付應用市場越做越大,他們希望將其接口開放給其他公司,以使自己的公司獲得更多的現金流。


首先,想要集成PayApp的公司B需要向公司A進行註冊,註冊成功後A公司分配給公司B三個東西,一個獨一無二的ID,一個public key,一個private key。這三個信息都是敏感的,不能泄露給公司A和公司B之外的其他公司。


當第三方應用想要調用PayApp時,需要傳入上面分配的三個參數傳遞給PayApp,PayApp在跟A公司的支付網關進行交互,然後將支付結果遞交給調用者。


假如此時,有一個***開發了一個惡意應用,並且將包名取得跟PayApp一樣。然後他將PayApp從手機上刪除,裝上自己的應用,那麼當公司B的應用再次調用支付接口時,就把所有的信息傳遞給了***自己的應用!


公司A爲了防止這種情況發生,專門開發了一個支付sdk,名字叫“PaySdk”,該sdk在調用PayApp前會對PayApp的簽名進行校驗,當校驗通過時,纔會將數據傳遞給PayApp。然後,所有想要調用PayApp接口的第三方應用,都需要繼承支付sdk。這樣就能防止信息被竊取。


下面詳細介紹簽名驗證的具體過程:


首先,我們需要對android應用簽名有一個基本瞭解:

1. 任何安裝到android設備上的應用都已經被簽名,即使debug狀態的app也已經用debug的keystore簽過名。

2. 需要發佈的應用一定要用release的keystore進行簽名。

3. 一個公司的release keystore只應該自己使用,不能泄露給其他人活公司。

4. 一個應用可能有多個簽名。


關於如何生成keystore,並且給一個應用簽名,可以查看官網教程:http://developer.android.com/intl/zh-cn/tools/publishing/app-signing.html


我們是通過對比簽名的hash值來確保其完整性的,所以在此之前,我們應該獲取release keystore對應的簽名的hash值,這樣在程序運行時才能進行比對。關於簽名的hash值,我們可以通過下面的代碼來獲取:



PackageInfo pkgInfo;

try {

    pkgInfo = mActivityContext.getPackageManager().getPackageInfo(targetPkg, PackageManager.GET_SIGNATURES);

} catch (PackageManager.NameNotFoundException e) {

    Toast.makeText(mActivityContext, "The target package is not found!", Toast.LENGTH_SHORT).show();

    e.printStackTrace();

    return;

}

for (Signature signature : pkgInfo.signatures) {

    try {

        Log.i(TAG, “hash: " + Base64.encodeToString(MessageDigest.getInstance("SHA").digest(signature.toByteArray()), Base64.NO_WRAP));

    } catch (NoSuchAlgorithmException e) {

        e.printStackTrace();

    }

}



上面代碼中,”targetPkg”應該被替換爲你想要獲取的應用的包名。代碼運行後,log輸出如下:


04-28 13:30:34.259 1123-1123/com.zlsam.signchecher I/MainActivity: hash: 6qX30I5Kpx4agIeolKla75oO+zA=


這裏我們的PaySdk需要將“hash:”後面的那個字符串記錄下來,本例中是“6qX30I5Kpx4agIeolKla75oO+zA=”。一個應用可能有多個簽名,因此,我們需要記錄和比對所有的簽名。


然後,當第三方應用通過PaySdk調用支付時,PaySdk首先通過上面代碼獲取應用包”com.testa.pay”的所有簽名hash,然後檢查這些動態獲取的hash值是否都在之前記錄下來的hash當中。如果是,那麼驗證通過,否則驗證失敗。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章