美文网首页
防止二次打包

防止二次打包

作者: 假_f89c | 来源:发表于2019-07-23 01:06 被阅读0次

    二次打包的危害性

    如果你没有对你的应用做任何的安全保障措施,那么你的应用就非常的危险

    首先了解一下什么是二次打包:

    二次打包

    通过工具apktool、dex2jar、jd-gui、DDMS、签名工具获取源码,嵌入恶意病毒、广告等行为再利用工具打包、签名,形成二次打包应用。

    此文最简单的解决方案:

    校验签名:可以在代码中判断签名信息是否被改变过,如果签名不一致就退出程序,以防止 apk 被重新打包。

    代码如下:

    public class SecondPackage {

        private final static String TAG = "SecondPackage";

        public SecondPackage(Context context) {

            // TODO Auto-generated constructor stub

            this.context = context;

        }

        private Context context;

        /************protect second package*******************/

        private void byte2hex(byte b, StringBuffer buf) {

            char[] hexChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8',

                    '9', 'A', 'B', 'C', 'D', 'E', 'F'};

            int high = ((b & 0xf0) >> 4);

            int low = (b & 0x0f);

            buf.append(hexChars[high]);

            buf.append(hexChars[low]);

        }

        /*

        * Converts a byte array to hex string

        */

        public String toHexString(byte[] block) {

            StringBuffer buf = new StringBuffer();

            int len = block.length;

            for (int i = 0; i < len; i++) {

                byte2hex(block[i], buf);

                if (i < len - 1) {

                    buf.append(":");

                }

            }

            return buf.toString();

        }

        public boolean getSignInfo() {

            boolean checkright = false;

            try {

                PackageInfo packageInfo = context.getApplicationContext().getPackageManager().getPackageInfo(

                        "com.ctcf.originsign", PackageManager.GET_SIGNATURES);

                Signature[] signs = packageInfo.signatures;

                Signature sign = signs[0];

                String code = String.valueOf(sign.hashCode());

                MessageDigest md = MessageDigest.getInstance("MD5");

                md.update(sign.toByteArray());

                byte[] digest = md.digest();

                String res = toHexString(digest);

                Log.e(TAG, "apk md5:" + res);

                //if (code == xxxxxxxxx) {

                Log.i(TAG, "hashCode:" + code);

                //对比MD5值和hashcode是否和自己原来的MD5相同

    //            if (res.equals("dashcode")

    //                    && code == MD5值) {

                if (code.equals(Constants.Companion.getPACKAGE_MD5_KEY())) {

                    checkright = true;

                } else {

                    checkright = false;

                }

                //parseSignature(sign.toByteArray());

            } catch (Exception e) {

                e.printStackTrace();

            }

            return checkright;

        }

        void parseSignature(byte[] signature) {

            try {

                CertificateFactory certFactory = CertificateFactory

                        .getInstance("X.509");

                X509Certificate cert = (X509Certificate) certFactory

                        .generateCertificate(new ByteArrayInputStream(signature));

                byte[] buffer = cert.getEncoded();

                System.out.println("md5: " + new String(buffer));

            } catch (CertificateException e) {

                e.printStackTrace();

            }

        }

    }

    调用的代码中:

    if (!BuildConfig.DEBUG) {

                val sePa = SecondPackage(this)

                if (sePa.signInfo == false) {

                    finish()

                    return

                }

            }

    这种方案纯粹的字符比较都很容易破解掉,添加代码混淆后也比较容易破解。直接在 smali 中全局搜索干掉或修改你的签名验证逻辑就行了,实际上用处不大。

    其它靠谱方案

    2 签名验证放到 native 层用 NDK 开发

    这种验证稍微安全了一点,毕竟能逆向 C 和 C++ 的人要少一些。像我这种现在还不能逆向C的就无能为力了。

    但对于能逆向C的同学来说,也是很轻易的就改掉你的验证逻辑,可以考虑加上,毕竟还是有点用的。

    3 验证放到服务端

    感觉没什么鸟用,直接干掉或修改你接口的判断逻辑的就行了。

    4 可以使用第三方对接口请求数据进行验证,比如阿里聚安全,但是不知为毛。阿里聚安全已被下线不再提供服务,如果有其他比较靠谱的三方方案可以留言。一起学习

    相关文章

      网友评论

          本文标题:防止二次打包

          本文链接:https://www.haomeiwen.com/subject/abknlctx.html