试图在Android中创建应用程序校验和,但它没有改变

时间:2017-09-27 14:52:49

标签: java android apk checksum

我正在Android上开发一个应用程序,并且有法律要求生成应用程序校验和,可以记录以检查以后的篡改。我意识到这并不完全安全,但我有一个盒子可以打勾!

我正在尝试这一点,从https://www.programcreek.com/java-api-examples/index.php?class=java.util.zip.CheckedInputStream&method=read的示例中公然偷走了:

String apkPath = App.getContext().getPackageCodePath();
Log.i("Checksum", "getting checksum for " + apkPath);
Long chksum = null;
Log.i("Checksum", "Size: " + new File(apkPath).length());
Log.i("Checksum", "Date: " + new Date(new File(apkPath).lastModified()));

try {
    // Open the file and build a CRC32 checksum.
    FileInputStream fis = new FileInputStream(new File(apkPath));
    CRC32 chk = new CRC32();
    CheckedInputStream cis = new CheckedInputStream(fis, chk);
    byte[] buff = new byte[80];
    while (cis.read(buff) >= 0) ;
    chksum = chk.getValue();
} catch (Exception e) {
    e.printStackTrace();
}
Log.i("Checksum", "Checksum is  " + chksum);

运行正常,输出看起来不错:

09-27 15:17:35.775 17288-17288/com.test.checksum.checksum I/Checksum: getting checksum for /data/app/com.test.checksum.checksum-2/base.apk
09-27 15:17:35.775 17288-17288/com.test.checksum.checksum I/Checksum: Size: 3245610
09-27 15:17:35.775 17288-17288/com.test.checksum.checksum I/Checksum: Date: Wed Sep 27 15:17:03 BST 2017
09-27 15:17:37.075 17288-17288/com.test.checksum.checksum I/Checksum: And Checksum is  0DAD53E0

问题是更改代码似乎没有任何区别 - 所以这段代码:

String apkPath = App.getContext().getPackageCodePath();
Log.i("Checksum", "getting checksum for " + apkPath);
Long chksum = null;
Log.i("Checksum", "Size: " + new File(apkPath).length());
Log.i("Checksum", "Date: " + new Date(new File(apkPath).lastModified()));

//do something differently
Log.i("Checksum", "And now do something else!");
Toast toast = Toast.makeText(getApplicationContext(), "I'm doing something else!", Toast.LENGTH_SHORT);
toast.show();

try {
    // Open the file and build a CRC32 checksum.
    FileInputStream fis = new FileInputStream(new File(apkPath));
    CRC32 chk = new CRC32();
    CheckedInputStream cis = new CheckedInputStream(fis, chk);
    byte[] buff = new byte[80];
    while (cis.read(buff) >= 0) ;
    chksum = chk.getValue();
} catch (Exception e) {
    e.printStackTrace();
}
Log.i("Checksum", "Checksum is  " + String.format("%08X", chksum));

生成此输出:

09-27 15:45:51.085 29517-29517/com.test.checksum.checksum I/Checksum: getting checksum for /data/app/com.test.checksum.checksum-2/base.apk
09-27 15:45:51.085 29517-29517/com.test.checksum.checksum I/Checksum: Size: 3245610
09-27 15:45:51.085 29517-29517/com.test.checksum.checksum I/Checksum: Date: Wed Sep 27 15:45:30 BST 2017
09-27 15:45:51.085 29517-29517/com.test.checksum.checksum I/Checksum: And now do something else!
09-27 15:45:52.335 29517-29517/com.test.checksum.checksum I/Checksum: Checksum is  0DAD53E0

有人知道发生了什么事吗?所有代码都存在于此APK文件中,还是有更多?如果我使用File().list(),那么我会得到一堆包含XML文件的文件夹,我最终将其包含在我的校验和中,但除非我直接通过名称访问它,否则将隐藏APK文件。

谢谢,

本。

2 个答案:

答案 0 :(得分:0)

校验和应该从Stream中获取。即获得长值:

cis.getChecksum().getValue()

您正在做的是从一个永远不会更改的新实例化的CRC32对象中获取相同的长值。

通常会创建Stream:

CheckedInputStream cis = new CheckedInputStream(fis, new CRC32())

也就是说,您传入的校验和不是“out”变量。一旦计算完毕,你必须从Stream中获取它。

答案 1 :(得分:0)

这似乎与在调试器中运行有关 - 即使使用JDV的更改,我仍然每次都将0DAD53E0作为校验和,并且有趣的是每次都看到相同的文件长度。

如果我构建两个代码略有不同的APK文件并手动安装,那么一切似乎都能正常工作 - 安装每个APK文件会产生一个单独的校验和,但每个校验和的校验和是一致的。

我只能假设Android Studio调试器安装标准或核心APK文件,并在调试器中运行时从其他地方加载代码,如Visual Studio的.vshost.exe文件。

感谢您的时间,

本。