看到有的同学求应用如何验签(验证签名),这里,我来分享一下我们公司如何进行验签,如果有其他同学有更好的方法,请留言指导,共同进步。
首先说下,为什么要系统验签。想必大多数同学们肯定都反编译过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。