Android App運行時簽名校驗

有時候我們爲了防止自己的應用被反編譯後重新打包,不得不採取運行時進行簽名校驗的方式。
因爲會經常用到,所以在這裏整理了一下校驗方式。

public class SignCheck {
    private Context context;
    private String cer = null;
    private String realCer = null;
    private static final String TAG = "SignCheck";
 
    public SignCheck(Context context) {
        this.context = context;
        this.cer = getCertificateSHA1Fingerprint();
    }
 
    public SignCheck(Context context, String realCer) {
        this.context = context;
        this.realCer = realCer;
        this.cer = getCertificateSHA1Fingerprint();
    }
 
    public String getRealCer() {
        return realCer;
    }
 
    /**
     * 設置正確的簽名
     *
     * @param realCer
     */
    public void setRealCer(String realCer) {
        this.realCer = realCer;
    }
 
    /**
     * 獲取應用的簽名
     *
     * @return
     */
    public String getCertificateSHA1Fingerprint() {
        //獲取包管理器
        PackageManager pm = context.getPackageManager();
 
        //獲取當前要獲取 SHA1 值的包名,也可以用其他的包名,但需要注意,
        //在用其他包名的前提是,此方法傳遞的參數 Context 應該是對應包的上下文。
        String packageName = context.getPackageName();
 
        //返回包括在包中的簽名信息
        int flags = PackageManager.GET_SIGNATURES;
 
        PackageInfo packageInfo = null;
 
        try {
            //獲得包的所有內容信息類
            packageInfo = pm.getPackageInfo(packageName, flags);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
 
        //簽名信息
        Signature[] signatures = packageInfo.signatures;
        byte[] cert = signatures[0].toByteArray();
 
        //將簽名轉換爲字節數組流
        InputStream input = new ByteArrayInputStream(cert);
 
        //證書工廠類,這個類實現了出廠合格證算法的功能
        CertificateFactory cf = null;
 
        try {
            cf = CertificateFactory.getInstance("X509");
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        //X509 證書,X.509 是一種非常通用的證書格式
        X509Certificate c = null;
 
        try {
            c = (X509Certificate) cf.generateCertificate(input);
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        String hexString = null;
 
        try {
            //加密算法的類,這裏的參數可以使 MD4,MD5 等加密算法
            MessageDigest md = MessageDigest.getInstance("SHA1");
 
            //獲得公鑰
            byte[] publicKey = md.digest(c.getEncoded());
 
            //字節到十六進制的格式轉換
            hexString = byte2HexFormatted(publicKey);
 
        } catch (NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (CertificateEncodingException e) {
            e.printStackTrace();
        }
        return hexString;
    }
 
    //這裏是將獲取到得編碼進行16 進制轉換
    private String byte2HexFormatted(byte[] arr) {
 
        StringBuilder str = new StringBuilder(arr.length * 2);
 
        for (int i = 0; i <arr.length; i++) {
            String h = Integer.toHexString(arr[i]);
            int l =h.length();
            if (l == 1)
                h = "0" + h;
            if (l > 2)
                h = h.substring(l - 2, l);
            str.append(h.toUpperCase());
            if (i < (arr.length - 1))
                str.append(':');
        }
        return str.toString();
    }
 
    /**
     * 檢測簽名是否正確
     * @return true 簽名正常 false 簽名不正常
     */
    public boolean check() {
 
        if (this.realCer != null) {
            cer = cer.trim();
            realCer = realCer.trim();
            if (this.cer.equals(this.realCer)) {
                return true;
            }
        }else {
            Log.e(TAG, "未給定真實的簽名 SHA-1 值");
        }
        return false;
    }
}

使用方法:
首先使用 keytool 獲取簽名的 sha-1 值,命令爲 keytool -list -v -keystore xxx.jks (將 xx.jks 換成你的應用簽名所用文件, 這裏會提示輸入 keystore 的密碼 ps:簽名文件在eclipse 是 .keystore 文件, 在 Android Studio中就是 .jks 文件))

然後使用如下代碼校驗簽名:


SignCheck signCheck = new SignCheck(this,"27:19:6E:38:6B:87:5E:76:AD:F7:00:E7:EA:84:E4:C6:EE:E3:3D:FA");
  if(signCheck.check()) {
  //TODO 簽名正常
  }else                {
  //TODO 簽名不正確
  newAlertDialog.Builder(this).setMessage("請前往官方渠道下載正版 app, http://.....").setPositiveButton("確定",null).show();
  }



作者:奈文_摩爾
鏈接:https://www.jianshu.com/p/50f2a8db2ab0
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。

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