Файл, содержащий собственную контрольную сумму - PullRequest
46 голосов
/ 13 июля 2009

Можно ли создать файл, который будет содержать собственную контрольную сумму (MD5, SHA1 и т. Д.)? Под расстроенными джокерами я подразумеваю контрольную сумму в простой форме, а не функцию ее вычисления.

Ответы [ 12 ]

33 голосов
/ 26 июля 2011

Я создал фрагмент кода на C, затем запустил bruteforce менее чем за 2 минуты и получил это чудо:

The CRC32 of this string is 4A1C449B

Обратите внимание, что после предложения не должно быть символов (конец строки и т. Д.).

Вы можете проверить это здесь: http://www.crc -online.com.ar / index.php? D = + CRC32 + из + this + string + равно + 4A1C449B & en = Calcular + CRC32

Это тоже забавно:

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

Исходный код (извините, это немного грязно) здесь: http://www.latinsud.com/pub/crc32/

17 голосов
/ 13 июля 2009

Да. Это возможно, и это обычно с простыми контрольными суммами. Получить файл для включения его собственного md5sum было бы довольно сложно.

В самом простом случае создайте значение контрольной суммы, которое приведет к тому, что суммарный модуль будет равен нулю Функция контрольной суммы тогда становится чем-то вроде

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

Если контрольная сумма становится частью файла и проверяется сама. Очень распространенным примером этого является алгоритм Луна , используемый в номерах кредитных карт. Последняя цифра является контрольной цифрой и сама является частью 16-значного числа.

12 голосов
/ 25 июля 2012

Проверьте это:

echo -e '#!/bin/bash\necho My cksum is 918329835' > magic
8 голосов
/ 11 марта 2013

«Хотелось бы, чтобы мой 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 минут для поиска всего пространства crc32 от 00000000 до ffffffff, выполняя около 1,8 миллиона тестов в секунду. Это было максимум одного ядра.

Я довольно новичок в Java, поэтому любые конструктивные комментарии к моему коду будут приветствоваться.

«Мой crc32 был c8cb204, и все, что я получил, это паршивая футболка!»

7 голосов
/ 13 июля 2009

Конечно, это возможно. Но одно из применений контрольных сумм заключается в обнаружении подделки файла - как вы узнаете, был ли файл изменен, если модификатор также может заменить контрольную сумму?

5 голосов
/ 13 июля 2009

Конечно, вы можете объединить дайджест самого файла до конца файла. Чтобы проверить это, вы должны вычислить дайджест всех, кроме последней части, а затем сравнить ее со значением в последней части. Конечно, без какой-либо формы шифрования любой может пересчитать дайджест и заменить его.

редактировать

Я должен добавить, что это не так уж необычно. Одним из методов является объединение CRC-32, чтобы CRC-32 всего файла (включая этот дайджест) был равен нулю. Это не будет работать с дайджестами, основанными на криптографических хешах.

2 голосов
/ 13 июля 2009

Я не знаю, правильно ли я понимаю ваш вопрос, но вы могли бы сделать первые 16 байтов файла контрольной суммой остальной части файла.

Поэтому перед записью файла вы вычисляете хеш, сначала записываете значение хеша, а затем записываете содержимое файла.

1 голос
/ 07 сентября 2011

В библиотеке python-stdnum есть аккуратная реализация алгоритма Luhn Mod N ( см. Luhn.py ). Функция calc_check_digit вычислит цифру или символ, который при добавлении в файл (выраженный в виде строки) создаст действительную строку Luhn Mod N. Как отмечалось во многих ответах выше, это дает проверку правильности файла, но не обеспечивает значительной защиты от подделки. Получатель должен знать, какой алфавит используется для определения действительности Luhn mod N.

1 голос
/ 05 мая 2010

Если задается вопрос, может ли файл содержать свою собственную контрольную сумму (в дополнение к другому содержимому), ответ тривиально да для контрольных сумм фиксированного размера, поскольку файл может содержать все возможные значения контрольной суммы .

Если вопрос состоит в том, может ли файл состоять из его собственной контрольной суммы (и ничего больше), тривиально построить алгоритм контрольной суммы, который сделал бы такой файл невозможным: для n-байтовой контрольной суммы, возьмите двоичное представление первых n байтов файла и добавьте 1. Поскольку также очень просто создать контрольную сумму, которая всегда кодирует себя (т. е. сделать выше, не добавляя 1), ясно, что есть некоторые контрольные суммы, которые может кодируют себя, а некоторые, которые не могут . Вероятно, было бы довольно сложно определить, какая из них является стандартной контрольной суммой.

0 голосов
/ 05 мая 2010

Существует много способов встраивания информации для обнаружения ошибок передачи и т. Д. Контрольные суммы CRC хороши при обнаружении серий последовательных переворотов битов и могут быть добавлены таким образом, что контрольная сумма всегда равна, например. 0. Однако такие контрольные суммы (включая коды с исправлением ошибок) легко воссоздать и не остановить злонамеренное вмешательство.

Невозможно встроить что-либо в сообщение, чтобы получатель мог проверить его подлинность, если получатель ничего не знает об отправителе или от него. Например, получатель может поделиться секретным ключом с отправителем. Затем отправитель может добавить зашифрованную контрольную сумму (которая должна быть криптографически защищена, например, md5 / sha1). Также возможно использовать асимметричное шифрование, когда отправитель может опубликовать свой открытый ключ и подписать контрольную сумму / хэш md5 своим закрытым ключом. Затем хеш и подпись могут быть помечены на данных как новый вид контрольной суммы. Это все время делается в интернете.

Тогда остаются следующие проблемы: 1. Как получатель может быть уверен, что он получил правильный открытый ключ, и 2. Насколько все это безопасно в действительности? Ответ на 1 может отличаться. В Интернете принято, чтобы открытый ключ был подписан кем-то, кому все доверяют. Другое простое решение заключается в том, что получатель получил открытый ключ от личной встречи ... Ответ на вопрос 2 может меняться изо дня в день, но то, что стоит принуждать к сегодняшнему дню, вероятно, будет дешевым, чтобы сломать его в будущем , К тому времени, мы надеемся, появились новые алгоритмы и / или увеличенные размеры ключей.

...