看到有的同学求应用如何验签(验证签名),这里,我来分享一下我们公司如何进行验签,如果有其他同学有更好的方法,请留言指导,共同进步。

首先说下,为什么要系统验签。想必大多数同学们肯定都反编译过android apk吧,也许有的同学还知道有一些小作坊,专门做一些把apk反编译之后加入广告,再次进行打包,投放到市场的工作。这不仅危害了原有开发者的利益,也危害了使用用户的权益。

我们要做到的就是,被再次打包后的应用无法和应用的后台进行交互。

上一段获取签名信息的方法:

public static String[] getCertMsg(String packageName, Context cxt) {
        String[] certMsg = new String[2];
        PackageInfo pis;
        try {
            pis = cxt.getPackageManager().getPackageInfo(cxt.getPackageName(),
                    PackageManager.GET_SIGNATURES);
            Signature[] sigs = pis.signatures; // 签名
            CertificateFactory certFactory = CertificateFactory
                    .getInstance("X.509");
            // 获取证书
            X509Certificate cert = (X509Certificate) certFactory
                    .generateCertificate(new ByteArrayInputStream(sigs[0]
                            .toByteArray()));
            // 可根据证书发行者来判断该应用是否被二次打包(被破解的应用重新打包后,签名与原包一定不同,据此可以判断出该应用是否被人做过改动)
            certMsg[0] = cert.getIssuerDN().toString();  //证书发行者
            certMsg[1] = cert.getSubjectDN().toString(); 
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return certMsg;
    }

通过这个方法我们可以拿到签名文件的信息,进而我们可以对这个些信息进行加密处理。
我们公司用的是FNV1 Hash算法进行加密,大家有性趣的可以去google这个算法,百度不怎么给力,查不到什么资料。

剩下的我们要做的就是,通过拿到加密之后的签名信息存储到后台,同时作为应用每只访问后台报文的一个常量,当被重新打包过的apk访问应用的后台,后台要对签名信息进行校验,如果校验不正确,我们当然不能返回正确的信息,我们会返回包含有应用被重新打包的特征码,在应用前台弹出窗体,显示“应用非官方”之类的信息,提示用户去下载正确的apk。