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

Trying to create app checksum in Android, but it's not changing

我正在 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 文件是隐藏的。

谢谢,

本.

应该从流中获取校验和。即,获取 long 值:

cis.getChecksum().getValue()

您正在做的是从从未更改过的新实例化的 CRC32 对象中获取相同的 long 值。

通常 Stream 是这样创建的:

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

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

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

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

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

谢谢你的时间,