Java自校验程序(自动校验和)

Java自校验程序(自动校验和),java,checksum,self,Java,Checksum,Self,我必须分析一个小的java自检程序,这里是示例 public class tamper { public static int checksum_self () throws Exception { File file = new File ("tamper.class"); FileInputStream fr = new FileInputStream (file); int result;

我必须分析一个小的java自检程序,这里是示例

public class tamper {
      public static int checksum_self () throws Exception {
          File file = new File ("tamper.class");
          FileInputStream fr = new FileInputStream (file);
          int result;                   // Compute the checksum

          DigestInputStream sha = new DigestInputStream(fr, MessageDigest.getInstance("SHA"));
   byte[] digest = sha.getMessageDigest();

    int result = 12  // why???
    for(int i=0;i<=digest;i++)
     {
     result = (result + digest[i]) % 16 /// modulus 16 to have the 16 first bytes but why ??
    }

    return result;
      }

      public static boolean check1_for_tampering () throws Exception {
            return checksum_self () != 10; 
      }

      public static void main (String args[]) throws Exception {
          if (check1_for_tampering ()) {
            System.exit (-1);
          }

      }
}
公共类篡改{
公共静态int校验和_self()引发异常{
File File=新文件(“tamper.class”);
FileInputStream fr=新的FileInputStream(文件);
int result;//计算校验和
DigestInputStream sha=新的DigestInputStream(fr,MessageDigest.getInstance(“sha”));
字节[]摘要=sha.getMessageDigest();
int result=12//为什么???

for(int i=0;imod 16不给出最后16个字节,甚至不给出最低的4位。它给出n/16的剩余部分。这很容易是负数和正数,并且不是累积摘要字节的好方法

两个随机文件产生相同结果的几率为1/31

我能想到的最简单的方法是

return new String(digest, 0).hashCode();

两个文件可能有40亿分之一的机会拥有相同的哈希代码,而且代码要短得多。

也许这个示例代码的作者不想检查摘要的整个16字节,所以他决定对哈希进行哈希,这就是mod 16操作的目的。它对摘要的前16个字节进行模16哈希(更具体地说,它是摘要的4位摘要),然后将结果与10进行比较。 如果我错了,请纠正我,但我认为值12和10是随机选择的,以确保实际哈希值与其检查的值匹配


正如Peter所说,这不是一个非常完美的解决方案。

可能是这样,因为如果没有模,将很难嵌入校验和。想象一下你已经编写了程序。你可以一次编写所有内容,但要获得正确的校验和,你必须进行实验

假设您编写的校验和模为4。开始时,您将该值与0进行比较。您运行该程序,但它检测到该值被篡改。为什么?因为您在编写整个源代码之前不知道校验和。由于校验和值嵌入其中,所以源代码的每次更改都会更改校验和

所以这就像一只狗追逐自己的尾巴。或者一条蛇吃掉自己的尾巴。从技术上讲,这是一个动态系统的情况,其中有反馈回路。好了,类比就够了

让它工作的唯一方法是实验。从校验和等于零开始编译。它很可能会识别出它被篡改了(不正确),因为你有大约1/4的概率(因为任何模4的值可以有4个值)正确猜测。接下来将值改为1。如果不起作用,则改为2,最后改为3

其中一个可以匹配,但具有较低的模值会降低检测篡改的可能性。因此,值16基本上是一个折衷方案。您希望将模值保持在尽可能低的水平,以获得合理的较低猜测量。另一方面,您希望算法通过具有较高的模值来防止篡改