1

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

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

例子:

假设我有文件 A.java 和 B.java。我想计算 A.java CRC32/MD5 并将此值存储在 B.java 中,以便在 B.java 执行时重新计算 A.java 并将其与已知值进行比较

4

3 回答 3

3

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

于 2012-11-19T08:56:29.520 回答
1
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;
}
于 2014-12-20T15:17:20.190 回答
1

使用java.io.BufferedReader将 A.java 的内容转换为字符串,然后执行以下操作:

public byte[] getMD5(String fileAContents) throws NoSuchAlgorithmException {
     MessageDigest messageDigest = MessageDigest.getInstance("MD5");
     messageDigest.update(fileAContents.getBytes());
     return messageDigest.digest();
}
于 2012-11-19T05:10:13.153 回答