APK校验码校验规则

来源:互联网 发布:西安软件开发公司 编辑:程序博客网 时间:2024/05/19 02:31

获取签名证书keystoreSHA1值和完整性校验获取的classes.dexSHA-1哈希值字符串进行拼接,使用MD5加密参数传入后台做比对,根据返回结果是否进行下一步登录操作

1.签名证书文件校验码

获取签名证书的SHA1

 

2.完整性校验

对签名文件中classes.dex哈希值的校验

       

Android工程代码经编译打包生成apk包后,开发者需要对其签名才能在安卓市场上发布供用户下载和安装。对apk包签名后,会在原apk包结构基础上加入META-INF文件目录。

       

META-INF文件目录下含有三个文件:MANIFEST.MF文件、ANDROIDD.SF文件、ANDROIDD.RSA文件,META_INF目录文件结构如下图所示:

 

其中,MANIFEST.MF文件描述了在签名时,签名工具对apk包中各个文件摘要计算后的哈希值,并对哈希值做了Base64编码。MANIFEST.MF文件中描述的classes.dex文件的SHA-1哈希值如下图所示:

 

一旦攻击者对APK中反编译并篡改代码,经二次打包签名后的classes.dex文件的SHA-1必定改变,因此,我们可以将该文件中的classes.dex文件的SHA-1哈希值保存起来作为校验对比值,应用程序启动时读取apk安装包中的MANIFEST.MF文件,解析出classes.dexSHA-1哈希值,然后与原SHA-1哈希值进行比较,判断此APK包代码文件是否被篡改。

 

       通过检查签名文件classes.dex文件的哈希值来判断代码文件是否被篡改的java实现代码如下所示:

 

/**

  * 通过检查签名文件classes.dex文件的哈希值来判断代码文件是否被篡改 

  *

  * @param context    上下文

  * @param orginalSHA 原始Apk包的SHA-1

  */

    public  static  void  apkVerifyWithSHA(Context context, String orginalSHA) {

        // 获取Apk包存储路径  

        String apkPath = context.getPackageCodePath();

        FileInputStream fis = null;

        try {

            //Java自带的加密类

            MessageDigest dexDigest = MessageDigest.getInstance("SHA-1");

            //设置缓存区数组

            byte[] bytes = new byte[1024];

            int byteCount;

            //通过文件读取apk文件 

            fis = new FileInputStream(new File(apkPath));

            while ((byteCount = fis.read(bytes)) != -1) {

                //使用指定的 byte数组更新

                dexDigest.update(bytes, 0, byteCount);

            }

            //计算apk文件的哈希值  

            BigInteger bigInteger = new BigInteger(1, dexDigest.digest());

            String sha = bigInteger.toString(16);

            // 将得到的哈希值与原始的哈希值进行比较校验  

            if (!sha.equals(orginalSHA)) {

                // 验证失败则退出程序 

                android.os.Process.killProcess(android.os.Process.myPid());

            }

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            try {

                if (fis != null) {

                    fis.close();

                }

            } catch (IOException e) {

                e.printStackTrace();

            }

        }

    }

0 0
原创粉丝点击