web-dev-qa-db-fra.com

Fichier contenant sa propre somme de contrôle

Est-il possible de créer un fichier qui contiendra sa propre somme de contrôle (MD5, SHA1, peu importe)? Et pour contrarier les jokers, je veux dire une somme de contrôle en clair, et non une fonction qui la calcule.

46
zakovyrya

J'ai créé un morceau de code en C, puis j'ai exécuté bruteforce pendant moins de 2 minutes et j'ai obtenu cette merveille:

The CRC32 of this string is 4A1C449B

Notez qu'il ne doit y avoir aucun caractère (fin de ligne, etc.) après la phrase.

Vous pouvez le vérifier ici: http://www.crc-online.com.ar/index.php?d=The+CRC32+of+this+string+is+4A1C449B&en=Calcular+CRC32

Celui-ci est aussi amusant:

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

Le code source (désolé c'est un peu brouillon) ici: http://www.latinsud.com/pub/crc32/

33
LatinSuD

Oui. C'est possible, et c'est courant avec les sommes de contrôle simples. Obtenir un fichier à inclure son propre md5sum serait assez difficile. 

Dans le cas le plus élémentaire, créez une valeur de somme de contrôle qui fera que le module ajouté soit égal à zéro. La fonction de somme de contrôle devient alors quelque chose comme

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

Si la somme de contrôle devient alors une partie du fichier et est vérifiée elle-même. Un exemple très courant est l’algorithme Luhn utilisé dans les numéros de carte de crédit. Le dernier chiffre est un chiffre de contrôle et fait lui-même partie du numéro à 16 chiffres.

17
brianegge

Vérifie ça:

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

"Je souhaite que mon crc32 soit 802892ef ..."

Eh bien, je pensais que c'était intéressant. Aujourd'hui, j'ai codé un petit programme Java pour détecter les collisions. Je pensais le laisser ici au cas où quelqu'un le trouverait utile:

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());
    }

}

Le résultat:

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

Notez que les points à la fin du message font en réalité partie du message.

Sur mon i5-2500, il fallait environ 40 minutes pour parcourir l’espace crc32 de 00000000 à ffffffff, soit environ 1,8 million de tests/seconde. C'était au maximum un noyau.

Je suis assez nouveau avec Java, donc tout commentaire constructif sur mon code serait apprécié.

"Mon crc32 était c8cb204, et tout ce que j'ai obtenu était ce t-shirt moche!"

8
localhost

Certainement, c'est possible. Mais l’une des utilisations des sommes de contrôle est de détecter la falsification d’un fichier - comment savoir si un fichier a été modifié, si le modificateur peut également remplacer la somme de contrôle?

7
Mark Ransom

Bien sûr, vous pouvez concaténer le résumé du fichier lui-même à la fin du fichier. Pour le vérifier, vous devez calculer le résumé de toutes les parties sauf la dernière, puis le comparer à la valeur de la dernière partie. Bien sûr, sans cryptage, n'importe qui peut recalculer le résumé et le remplacer.

modifier

Je devrais ajouter que ce n'est pas si inhabituel. Une technique consiste à concaténer un CRC-32 de sorte que le CRC-32 de l'ensemble du fichier (y compris ce résumé) soit égal à zéro. Cela ne fonctionnera pas avec les résumés basés sur des hachages cryptographiques, cependant.

4
Steven Sudit

Je ne sais pas si je comprends bien votre question, mais vous pouvez utiliser les 16 premiers octets du fichier comme somme de contrôle du reste du fichier.

Ainsi, avant d'écrire un fichier, calculez le hachage, écrivez d'abord la valeur de hachage, puis écrivez le contenu du fichier.

2
Philippe Leybaert

Il existe une implémentation soignée de l’algorithme Luhn Mod N dans la bibliothèque python-stdnum ( voir luhn.py ). La fonction calc_check_digit calculera un chiffre ou un caractère qui, une fois ajouté au fichier (exprimé sous forme de chaîne), créera une chaîne Luhn Mod N valide. Comme indiqué dans de nombreuses réponses ci-dessus, cela permet de vérifier la validité du fichier, mais pas de sécurité significative contre la falsification. Le récepteur devra savoir quel alphabet est utilisé pour définir la validité de Luhn modN.

1
Martin Juckes

Si la question demande si un fichier peut contenir sa propre somme de contrôle (en plus d’autres contenus), la réponse est trivialement oui pour les sommes de contrôle de taille fixe, puisqu’un fichier peut contenir toutes les valeurs de somme de contrôle possibles.

Si la question est de savoir si un fichier peut consister en sa propre somme de contrôle (et rien d’autre), il est trivial de construire un algorithme de somme de contrôle qui rendrait un tel fichier impossible: pour une somme de contrôle de n octets, prenez le binaire. représentation des n premiers octets du fichier et ajout de 1. Puisqu'il est également trivial de construire une somme de contrôle qui se code toujours (c.-à-d. faire ce qui précède sans ajouter 1), il existe clairement des sommes de contrôle que can se codent , et certains que ne peuvent pas . Il serait probablement assez difficile de dire laquelle de ces sommes est une somme de contrôle standard.

1
tloflin

Sûr.

Le moyen le plus simple consiste à exécuter le fichier via un algorithme MD5 et à incorporer ces données dans le fichier. Vous pouvez fractionner la somme de contrôle et la placer à des points connus du fichier (en fonction d'une taille de partie du fichier, par exemple 30%, 50%, 75%) si vous souhaitez essayer de la masquer.

De même, vous pouvez chiffrer le fichier ou chiffrer une partie du fichier (avec la somme de contrôle MD5) et l'intégrer au fichier. Edit J'ai oublié de dire que vous le feriez besoin de supprimer les données de contrôle avant de les utiliser.

Bien sûr, si votre fichier doit être facilement lisible par un autre programme, par ex. Word alors les choses deviennent un peu plus compliquées car vous ne voulez pas "corrompre" le fichier pour qu'il ne soit plus lisible.

0
ChrisBD

Vous pouvez bien sûr, mais dans ce cas, le condensé SHA de l'ensemble du fichier ne sera pas le SHA que vous avez inclus, car il s'agit d'une fonction de hachage cryptographique. le fichier change tout le hachage. Ce que vous recherchez est un checksum calculé en utilisant le contenu du fichier de manière à correspondre à un ensemble de critères.

0
bandi

Il existe de nombreuses façons d’incorporer des informations afin de détecter les erreurs de transmission, etc. Les totaux de contrôle CRC sont efficaces pour détecter des exécutions de bits inversés consécutifs et peuvent être ajoutés de telle sorte que le total de contrôle est toujours, par exemple. 0. Ces types de sommes de contrôle (y compris les codes de correction d'erreur) sont toutefois faciles à recréer et n'empêchent pas les tentatives de modification malveillantes.

Il est impossible d'intégrer quelque chose dans le message afin que le destinataire puisse vérifier son authenticité s'il ne sait rien d'autre de l'expéditeur. Le destinataire pourrait par exemple partager une clé secrète avec l'expéditeur. L'expéditeur peut ensuite ajouter une somme de contrôle chiffrée (qui doit être sécurisée de manière cryptographique, telle que md5/sha1). Il est également possible d'utiliser un cryptage asymétrique dans lequel l'expéditeur peut publier sa clé publique et signer la somme de contrôle/hachage md5 avec sa clé privée. Le hachage et la signature peuvent ensuite être étiquetés sur les données en tant que nouveau type de somme de contrôle. Cela se fait tout le temps sur internet de nos jours.

Les problèmes restants sont alors 1. Comment le destinataire peut-il être sûr d'avoir la bonne clé publique et 2. Quel est le niveau de sécurité de tous ces éléments dans la réalité ?. La réponse à 1 pourrait varier. Sur Internet, il est courant de faire signer la clé publique par quelqu'un en qui tout le monde a confiance. Une autre solution simple est que le destinataire reçoive la clé publique d'une réunion en personne ... La réponse à 2 peut changer de jour en jour, mais ce qu'il en coûterait de forcer aujourd'hui serait probablement peu coûteux de prendre une pause dans le futur. . À ce moment-là, de nouveaux algorithmes et/ou des tailles de clé agrandies sont apparus.

0
Markarian451