文件包含自己的校验和

时间:2009-07-13 07:04:12

标签: security checksum data-integrity

是否可以创建一个包含自己的校验和(MD5,SHA1等)的文件?而对于沮丧的笑话我的意思是校验和,而不是计算它的函数。

12 个答案:

答案 0 :(得分:33)

我在C中创建了一段代码,然后在不到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/

答案 1 :(得分:17)

是。这是可能的,并且它与简单的校验和很常见。获取文件以包含它自己的md5sum将是非常具有挑战性的。

在最基本的情况下,创建一个校验和值,使得总和模数等于零。然后校验和函数变成类似

的函数
(n1 + n2 ... + CRC) % 256 == 0

如果校验和随后成为文件的一部分,则自行检查。一个非常常见的例子是信用卡号码中使用的Luhn algorithm。最后一位是校验位,它本身就是16位数字的一部分。

答案 2 :(得分:12)

检查一下:

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

答案 3 :(得分:8)

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

好吧,我认为这很有趣所以今天我编写了一个小程序来查找碰撞。我以为我会把它留在这里以防有人发现它有用:

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到ffffffff搜索整个crc32空间,每秒进行大约180万次测试。它最大化了一个核心。

我对java很新,所以对我的代码有任何建设性意见。

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

答案 4 :(得分:7)

当然,这是可能的。但校验和的一个用途是检测文件的篡改 - 如果修改文件也可以替换校验和,您如何知道文件是否被修改?

答案 5 :(得分:4)

当然,您可以将文件本身的摘要连接到文件末尾。要检查它,您将计算除最后一部分之外的所有摘要,然后将其与最后一部分中的值进行比较。当然,如果没有某种形式的加密,任何人都可以重新计算摘要并替换它。

修改

我应该补充一点,这并不是那么不寻常。一种技术是连接CRC-32,以便整个文件(包括该摘要)的CRC-32为零。但是,这不适用于基于加密哈希的摘要。

答案 6 :(得分:2)

我不知道我是否正确理解了您的问题,但您可以将文件的前16个字节作为文件其余部分的校验和。

因此,在编写文件之前,先计算哈希值,先写入哈希值然后再写入文件内容。

答案 7 :(得分:1)

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

如果问题是一个文件是否包含它自己的校验和(没有别的),那么构造一个校验和算法会使这样的文件变得不可能是微不足道的:对于一个n字节的校验和,获取文件的前n个字节的二进制表示并添加1.因为构造一个始终对自身进行编码的校验和也很简单(即在不添加1的情况下执行上述操作),显然有一些校验和可以< / em>编码自己,有些不能。可能很难分辨出这些标准校验和中的哪一个。

答案 8 :(得分:1)

python-stdnum库(see luhn.py)中有Luhn Mod N算法的简洁实现。 calc_check_digit函数将计算一个数字或字符,当附加到文件(表示为字符串)时,将创建一个有效的Luhn Mod N字符串。正如上面的许多答案中所指出的,这可以对文件的有效性进行健全性检查,但是没有明显的防止篡改的安全性。接收者需要知道用什么字母来定义Luhn mod N的有效性。

答案 9 :(得分:0)

有许多方法可以嵌入信息以便检测传输错误等.CRC校验和擅长检测连续位翻转的运行,并且可以以校验和总是例如这样的方式添加。然而,这些校验和(包括纠错码)很容易重现,并且不会阻止恶意篡改。

如果接收者对发送者没有任何其他信息,接收者可以验证其真实性是不可能的。接收器可以例如与发送者共享秘密密钥。然后,发送方可以附加加密的校验和(需要加密安全,例如md5 / sha1)。也可以使用非对称加密,其中发送者可以发布他的公钥并用他的私钥签署md5校验和/哈希。然后可以将散列和签名作为新类型的校验和标记到数据上。现在这种情况一直在互联网上完成。

剩下的问题是1.接收者如何确定他获得了正确的公钥?2。现实中所有这些东西的安全性如何? 1的答案可能会有所不同。在互联网上,让每个人都信任的公钥签名是很常见的。另一个简单的解决方案是接收者从个人会议中获得了公钥...... 2的答案可能会日常变化,但强迫日复一日的成本可能很便宜,以便在将来打破一些时间。到那时,新的算法和/或扩大的密钥大小有望出现。

答案 10 :(得分:-1)

不确定

最简单的方法是通过MD5算法运行文件并将该数据嵌入文件中。如果您想尝试隐藏它,可以拆分校验和并将其放在文件的已知点(基于文件的部分大小,例如30%,50%,75%)。

同样,您可以加密文件,或加密文件的一部分(以及MD5校验和)并将其嵌入文件中。 的修改 我忘了说你需要在使用它之前删除校验和数据。

当然,如果您的文件需要其他程序可以轻松读取,例如然后事情会变得有点复杂,因为你不想“破坏”文件,使其不再可读。

答案 11 :(得分:-1)

当然,您可以,但在这种情况下,整个文件的SHA摘要将不是您包含的SHA,因为它是加密哈希函数,因此更改文件中的单个位会更改整个哈希值。你要找的是使用文件内容计算的checksum,以匹配一组标准。