Java 如何使用我的APK计算特定文件的CRC32/MD5

Java 如何使用我的APK计算特定文件的CRC32/MD5,java,android,Java,Android,我想在APK中计算应用程序中特定文件活动的CRC或MD5,以便在另一个文件中比较该值,并确保第一个文件未被篡改 我可以这样做吗?是这样的,你能用它指导我吗 例如: 假设我有文件A.java和B.java。我想计算A.java CRC32/MD5并将该值存储在B.java中,这样当B.java执行时,它将重新定义A.java并将其与已知值进行比较使用A将A.java的内容转换为字符串,并按如下步骤进行: public byte[] getMD5(String fileAContents) thro

我想在APK中计算应用程序中特定文件活动的CRC或MD5,以便在另一个文件中比较该值,并确保第一个文件未被篡改

我可以这样做吗?是这样的,你能用它指导我吗

例如:


假设我有文件A.java和B.java。我想计算A.java CRC32/MD5并将该值存储在B.java中,这样当B.java执行时,它将重新定义A.java并将其与已知值进行比较

使用A将A.java的内容转换为字符串,并按如下步骤进行:

public byte[] getMD5(String fileAContents) throws NoSuchAlgorithmException {
     MessageDigest messageDigest = MessageDigest.getInstance("MD5");
     messageDigest.update(fileAContents.getBytes());
     return messageDigest.digest();
}

使用A将A.java的内容转换为字符串,并按如下步骤进行操作:

public byte[] getMD5(String fileAContents) throws NoSuchAlgorithmException {
     MessageDigest messageDigest = MessageDigest.getInstance("MD5");
     messageDigest.update(fileAContents.getBytes());
     return messageDigest.digest();
}

你不能这样做。Android上没有单独的类文件,您可以得到一个包含所有类和库的DEX文件。您必须计算classes.dex文件的散列并将其存储在资源文件中,因为将其放入类文件将更改总体散列值。但是,如果我反编译你的应用程序并更改你的classes.dex,我还可以更改资源,因此这并不能真正提供任何保护。当然,您可以尝试混淆或隐藏该值以使其更难处理,但是一些工具会查找CRC/MessageDigest引用,并简单地将它们挂钩以每次返回相同的值

你不能这么做。Android上没有单独的类文件,您可以得到一个包含所有类和库的DEX文件。您必须计算classes.dex文件的散列并将其存储在资源文件中,因为将其放入类文件将更改总体散列值。但是,如果我反编译你的应用程序并更改你的classes.dex,我还可以更改资源,因此这并不能真正提供任何保护。当然,您可以尝试混淆或隐藏该值以使其更难处理,但是一些工具会查找CRC/MessageDigest引用,并简单地将它们挂钩以每次返回相同的值

谢谢,但是当我的代码打包在apk文件中执行时,文件的路径会是什么呢?应该是这样。Java或。班我需要在运行时计算它谢谢,但是当我的代码在apk文件中打包时执行时,文件的路径会是什么?应该是这样。Java或。班我需要在运行时计算它谢谢你的洞察力,我如何计算DEX文件的散列值?只要是黑客的手工工作,我就很好。我只是不希望像luckypatcher这样的工具破解我的应用程序。你可以使用Context.getApplicationInfo.sourceDir来查找APK的位置,并找到classes.dex的lokk。提示:APK是一个zip文件。然后使用MessageDigest来计算散列。当然,像Lucky Patcher这样的东西会直接修改dalvik缓存,所以使用这种方法不会检测到这种情况。为了解决这个问题,你可以做一些技巧,比如用DexFile手动加载和优化内容,计算散列并与实际缓存中的内容进行比较,但通常不值得这样做,除非你要使用特定的工具/exploit.Accepted。这正是我想做的。我特别想和幸运的patcher打交道。你是说这个散列计算在这方面没有帮助?您是否有指向如何手动加载/优化或处理缓存的教程或指针的链接。我觉得你离我更近了,我只需要提示:这个是俄语的,但是有代码,通过谷歌翻译,你应该知道:谢谢你的洞察力,我如何计算DEX文件的散列值?只要是黑客的手工工作,我就很好。我只是不希望像luckypatcher这样的工具破解我的应用程序。你可以使用Context.getApplicationInfo.sourceDir来查找APK的位置,并找到classes.dex的lokk。提示:APK是一个zip文件。然后使用MessageDigest来计算散列。当然,像Lucky Patcher这样的东西会直接修改dalvik缓存,所以使用这种方法不会检测到这种情况。为了解决这个问题,你可以做一些技巧,比如用DexFile手动加载和优化内容,计算散列并与实际缓存中的内容进行比较,但通常不值得这样做,除非你要使用特定的工具/exploit.Accepted。这正是我想做的。我特别想和幸运的patcher打交道。你是说这个散列计算在这方面没有帮助?您是否有指向如何手动加载/优化或处理缓存的教程或指针的链接。我觉得你离我更近了,我需要的只是提示请相信:这是俄文的,但有代码,通过谷歌翻译,你应该知道:
public static void calculate(Context context) {

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

        ZipInputStream fis = get(context);
        System.out.println("fis: " + fis);

        byte[] dataBytes = new byte[1024];

        int nread = 0; 
        while ((nread = fis.read(dataBytes)) != -1) {
          md.update(dataBytes, 0, nread);
        };
        byte[] mdbytes = md.digest();

        //convert the byte to hex format method 1
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < mdbytes.length; i++) {
          sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
        }

        System.out.println("Digest(in hex format):: " + sb.toString());

        //convert the byte to hex format method 2
        StringBuffer hexString = new StringBuffer();
        for (int i=0;i<mdbytes.length;i++) {
            String hex=Integer.toHexString(0xff & mdbytes[i]);
            if(hex.length()==1) hexString.append('0');
            hexString.append(hex);
        }
        System.out.println("Digest(in hex format):: " + hexString.toString());

        if(fis!=null){
            fis.close();
        }
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static ZipInputStream get(Context context){

      // Get the path to the apk container.
    String apkPath = context.getApplicationInfo().sourceDir;
    JarFile containerJar = null;

    try {

        // Open the apk container as a jar..
        containerJar = new JarFile(apkPath);

        // Look for the "classes.dex" entry inside the container.
        ZipEntry zzz = containerJar.getEntry("classes.dex");

        // If this entry is present in the jar container 
        if (zzz != null) {

            System.out.println("long " + zzz.getCrc());

             // Get an Input Stream for the "classes.dex" entry
            InputStream in = containerJar.getInputStream(zzz);

             ZipInputStream zin = new ZipInputStream(in);

             return zin;
        }   

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (containerJar != null)
            try {
                containerJar.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }

    return null;
}