我必须分析一个小的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);
}
}
}但我真的不明白为什么要做mod 16,并将result = 12?
发布于 2011-01-04 04:11:50
这可能是因为如果没有模数就很难嵌入校验和。想象一下你已经写好了程序。你可以一次写完所有的代码,但是为了得到正确的校验和,你必须进行实验。
假设你写的是模数为4的校验和,一开始你把这个值和0进行比较。你运行这个程序,但它检测到它被篡改了。为什么?因为你不知道校验和,直到你写出完整的源代码。由于校验和值嵌入其中,因此每次更改源代码都会更改校验和。
所以它就像一条狗在追自己的尾巴。或者是蛇在吃自己的尾巴。从技术上讲,这是一个具有反馈回路的动态系统的情况。好了,类比说得够多了。
让它工作的唯一方法就是进行实验。从校验和等于零开始,然后编译。它很可能会识别出它被篡改了(不正确),因为你有大约1/4的概率(因为模4的任何值都可以有4个值)来正确猜测。接下来,将值更改为1。如果不起作用,则将值更改为2,最后更改为3。
它们中的一个可以匹配,但模数值较低会降低检测篡改的可能性。因此,值16基本上是一个折衷方案。您希望将模数值保持在尽可能低的水平,以获得合理的低猜测量。另一方面,您希望算法具有较高的模数值,从而具有很好的防篡改能力。
发布于 2011-01-04 04:07:46
模16不给出最后16个字节,甚至不给出最低的4位。它给出了n/ 16的余数。这很容易是负数和正数,这不是累积摘要字节的好方法。
两个随机文件产生相同结果的可能性为1/31。
我能想到的最简单的方法是
return new String(digest, 0).hashCode();两个文件有40亿分之一的机会拥有相同的散列代码,并且代码要短得多。
发布于 2011-01-04 04:11:28
也许这个示例代码的作者不想检查整个16个字节的摘要,所以他决定对哈希进行哈希,这就是mod 16操作的目的。它以16为模对摘要的前16个字节进行哈希运算(更具体地说,它是摘要的4位摘要),然后将结果与10进行比较。如果我错了,请纠正我,但我认为值12和10是随机选择的,以确保实际的哈希和检查的值是匹配的。
正如Peter所说,这不是一个非常完美的解决方案。
https://stackoverflow.com/questions/4587835
复制相似问题