包含它自己的校验和的文件

是否有可能创build一个文件,将包含自己的校验和(MD5,SHA1,无论)? 而打扰的笑话我的意思是校验和,而不是函数计算它。

是。 这是可能的,并且简单的校验和是常见的。 获得一个文件来包含它自己的md5sum将是相当具有挑战性的。

在最基本的情况下,创build一个校验和值,这将导致总和模数等于零。 校验和函数然后变成类似的东西

(n1 + n2 ... + CRC) % 256 == 0 

如果校验和成为文件的一部分,并且自己被检查。 一个非常常见的例子是用于信用卡号码的Luhnalgorithm 。 最后一位是一个校验位,它本身就是16位数字的一部分。

我用C创build了一段代码,然后运行了不到2分钟的暴力破解,

 The CRC32 of this string is 4A1C449B 

注意句子后面必须没有字符(行尾等)。

你可以在这里查看: http : //www.crc-online.com.ar/index.php?d=The+CRC32+of+this+string+is+ 4A1C449B& en=Calcular+CRC32

这一个也很有趣:

 I killed 56e9dee4 cows and all I got was... 

源代码(对不起,这有点乱)在这里: http : //www.latinsud.com/pub/crc32/

检查这个:

 echo -e '#!/bin/bash\necho My cksum is 918329835' > magic 

当然,这是可能的。 但是校验和的用途之一是检测文件的篡改 – 你如何知道文件是否被修改,修改器是否也可以replace校验和?

“我希望我的crc32是802892ef …”

那么,我认为这很有趣,所以今天我编写了一个Java程序来查找冲突。 以为我会留在这里,以防有人发现它有用:

 import java.util.zip.CRC32; public class Crc32_recurse2 { public static void main(String[] args) throws InterruptedException { long endval = Long.parseLong("ffffffff", 16); long startval = 0L; // startval = Long.parseLong("802892ef",16); //uncomment to save yourself some time float percent = 0; long time = System.currentTimeMillis(); long updates = 10000000L; // how often to print some status info for (long i=startval;i<endval;i++) { String testval = Long.toHexString(i); String cmpval = getCRC("I wish my crc32 was " + testval + "..."); if (testval.equals(cmpval)) { System.out.println("Match found!!! Message is:"); System.out.println("I wish my crc32 was " + testval + "..."); System.out.println("crc32 of message is " + testval); System.exit(0); } if (i%updates==0) { if (i==0) { continue; // kludge to avoid divide by zero at the start } long timetaken = System.currentTimeMillis() - time; long speed = updates/timetaken*1000; percent = (i*100.0f)/endval; long timeleft = (endval-i)/speed; // in seconds System.out.println(percent+"% through - "+ "done "+i/1000000+"M so far" + " - " + speed+" tested per second - "+timeleft+ "s till the last value."); time = System.currentTimeMillis(); } } } public static String getCRC(String input) { CRC32 crc = new CRC32(); crc.update(input.getBytes()); return Long.toHexString(crc.getValue()); } } 

输出:

 49.825756% through - done 2140M so far - 1731000 tested per second - 1244s till the last value. 50.05859% through - done 2150M so far - 1770000 tested per second - 1211s till the last value. Match found!!! Message is: I wish my crc32 was 802892ef... crc32 of message is 802892ef 

请注意,邮件末尾的点实际上是邮件的一部分。

在我的i5-2500上,要花费大约40分钟的时间,从00000000到ffffffffsearch整个crc32空间,每秒钟执行大约180万次testing。 这是最大的一个核心。

我对Java相当新,所以任何build设性的意见,我的代码将不胜感激。

“我的crc32是c8cb204,我得到的只是这个糟糕的T恤!

当然,您可以将文件摘要连接到文件末尾。 要检查它,你会计算除最后一部分之外的所有摘要,然后将它与最后一部分的值进行比较。 当然,没有某种forms的encryption,任何人都可以重新计算摘要并将其replace。

编辑

我应该补充说,这并不是那么不寻常。 一种技术是连接CRC-32,使整个文件(包括摘要)的CRC-32为零。 尽pipe如此,这对基于密码哈希的摘要不起作用。

我不知道如果我正确理解你的问题,但你可以使文件的前16个字节的文件的其余部分的校验和。

所以在写文件之前,你先计算哈希值,先写哈希值,然后写文件内容。

如果问题是询问文件是否可以包含自己的校验和(除了其他内容),对于固定大小的校验和来说,答案是微不足道的,因为文件可能包含所有可能的校验和值。

如果问题是一个文件是否可以包含自己的校验和(而没有其他的),那么构造一个校验和algorithm是不可能的:对于一个n字节的校验和,取前n个字节的二进制表示并添加1.由于构造一个始终编码自己的校验和也是微不足道的(即,在不添加1的情况下执行上述操作),显然有一些校验和可以对自己进行编码,有些则不能 。 可能很难分辨出这些标准校验和是哪一个。

python-stdnum库中的Luhn Mod Nalgorithm有一个很好的实现( 见luhn.py )。 calc_check_digit函数将计算一个数字或字符,当将其附加到文件(以string表示)时,将会创build一个有效的Luhn Mod Nstring。 正如在上面的许多答案中指出的那样,这将对文件的有效性进行完整性检查,但是对于篡改没有显着的安全性。 接收者需要知道用什么字母来定义Luhn mod N的有效性。

你当然可以,但是在这种情况下,整个文件的SHA摘要将不是你所包含的SHA文件,因为它是一个encryption散列函数,所以在文件中改变一个位就可以改变整个散列。 你正在寻找的是使用文件内容计算的校验和 ,以匹配一组标准。

当然。

最简单的方法是通过MD5algorithm运行文件并将该数据embedded到文件中。 如果你想尝试并隐藏它,你可以将检查总数分成几部分,并将其放在文件的已知点(基于文件的部分大小,例如30%,50%,75%)。

同样,您可以encryption文件,或者encryption文件的一部分(以及MD5校验和)并将其embedded到文件中。 编辑我忘了说,你需要在使用前删除校验和数据。

当然,如果您的文件需要被另一个程序(例如Word)轻易读取,那么事情会变得更复杂一些,因为您不希望“损坏”文件,使其不再可读。

为了检测传输错误有很多方法来embedded信息.CCR校验和擅长于检测连续位翻转的运行,并且可以以校验和总是例如0的方式被添加。这些types的校验和(包括错误更正代码)很容易重新创build,不会阻止恶意篡改。

在消息中embedded某些东西是不可能的,以便接收者可以validation其真实性,如果接收者对发送者没有任何其他信息。 接收者可以例如与发送者共享密钥。 然后发送者可以附加一个encryption的校验和(这需要encryption保护,比如md5 / sha1)。 也可以使用不对称encryption,发件人可以发布他的公钥并用他的私钥签名md5校验和/散列。 散列和签名可以作为一种新的校验和标记到数据上。 现在互联网上一直都是这样做的。

剩下的问题就是1.接收者怎么能确定他得到了正确的公钥呢?2.实际上这些东西有多安全? 答案1可能会有所不同。 在互联网上,有一个人人都信任的公共密钥是很常见的。 另一个简单的解决scheme是,接收者从个人会议中获得了公开密钥……对于2的答案可能会从日常变化,但是强迫到今天的代价会很便宜,打破未来一段时间。 到那个时候,新的algorithm和/或放大的密钥大小有望出现。