独自のチェックサム (MD5、SHA1 など) を含むファイルを作成することはできますか? そして、ジョーカーを混乱させるために、私はそれを計算する関数ではなく、単純なチェックサムを意味します。
12 に答える
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/
はい。それは可能であり、単純なチェックサムでは一般的です。ファイルに独自の md5sum を含めるのは非常に困難です。
最も基本的なケースでは、合計モジュラスがゼロになるチェックサム値を作成します。チェックサム関数は次のようになります
(n1 + n2 ... + CRC) % 256 == 0
チェックサムがファイルの一部になり、それ自体がチェックされる場合。これの非常に一般的な例は、クレジット カード番号で使用されるLuhn アルゴリズムです。最後の桁はチェック ディジットであり、それ自体が 16 桁の数字の一部です。
これをチェックして:
echo -e '#!/bin/bash\necho My cksum is 918329835' > magic
「私の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 では、00000000 から ffffffff までの crc32 スペース全体を検索するのに約 40 分かかり、1 秒あたり約 180 万回のテストが行われました。1つのコアを使い果たしていました。
私はJavaにかなり慣れていないので、コードに関する建設的なコメントをいただければ幸いです。
「私のcrc32はc8cb204で、手に入れたのはこのひどいTシャツだけでした!」
確かに、それは可能です。しかし、チェックサムの用途の 1 つは、ファイルの改ざんを検出することです。修飾子がチェックサムも置き換えることができる場合、ファイルが変更されているかどうかをどのように知るのでしょうか?
確かに、ファイル自体のダイジェストをファイルの最後に連結できます。それを確認するには、最後の部分を除くすべてのダイジェストを計算し、それを最後の部分の値と比較します。もちろん、なんらかの形式の暗号化がなければ、誰でもダイジェストを再計算して置き換えることができます。
編集
これはそれほど珍しいことではないことを付け加えておきます。1 つの手法は、CRC-32 を連結して、ファイル全体 (そのダイジェストを含む) の CRC-32 がゼロになるようにすることです。ただし、これは暗号化ハッシュに基づくダイジェストでは機能しません。
Luhn Mod N
python-stdnum ライブラリにアルゴリズムの適切な実装があります ( luhn.py を参照)。このcalc_check_digit
関数は数字または文字を計算し、ファイルに追加すると (文字列として表されます)、有効なLuhn Mod N
文字列が作成されます。上記の多くの回答で述べたように、これによりファイルの有効性に関する健全性チェックが行われますが、改ざんに対する重要なセキュリティはありません。受信者は、Luhn mod N の有効性を定義するために使用されているアルファベットを知る必要があります。
あなたの質問を正しく理解しているかどうかわかりませんが、ファイルの最初の 16 バイトを残りのファイルのチェックサムにすることができます。
したがって、ファイルを書き込む前に、ハッシュを計算し、最初にハッシュ値を書き込み、次にファイルの内容を書き込みます。
ファイルに (他のコンテンツに加えて) 独自のチェックサムを含めることができるかどうかという質問の場合、ファイルには可能なすべてのチェックサム値を含めることができるため、固定サイズのチェックサムの場合、答えは自明です。
ファイルが独自のチェックサム (およびそれ以外のもの) で構成されるかどうかが問題である場合、そのようなファイルを不可能にするチェックサム アルゴリズムを構築するのは簡単です: n バイトのチェックサムの場合、最初の n バイトのバイナリ表現を取得します。常にそれ自体をエンコードするチェックサムを作成することも簡単なので (つまり、1 を追加せずに上記を実行します)、明らかに、自分自身をエンコードできるチェックサムとできないチェックサムがあります。これらのどれが標準チェックサムであるかを判断するのはおそらく非常に難しいでしょう。
伝送エラーなどを検出するために情報を埋め込む方法は多数あります。CRC チェックサムは、連続するビット フリップの実行を検出するのに優れており、チェックサムが常に 0 になるような方法で追加される場合があります。これらの種類のチェックサム (エラーを含む)ただし、コードの修正) は簡単に再作成でき、悪意のある改ざんを止めることはできません。
受信者が送信者について他に何も知らない場合、受信者がその信頼性を検証できるように、メッセージに何かを埋め込むことは不可能です。たとえば、受信者は送信者と秘密鍵を共有できます。次に、送信者は暗号化されたチェックサム (md5/sha1 などの暗号学的に安全である必要があります) を追加できます。送信者が公開鍵を公開し、秘密鍵で md5 チェックサム/ハッシュに署名できる非対称暗号化を使用することもできます。ハッシュと署名は、新しい種類のチェックサムとしてデータにタグ付けできます。これは、今日インターネット上で常に行われています。
残りの問題は、1.受信者が正しい公開鍵を取得したことをどのように確認できるか、および2.これらすべてが実際にどの程度安全か?. 1 に対する答えは異なる場合があります。インターネットでは、誰もが信頼する誰かによって署名された公開鍵を持っているのが一般的です。別の簡単な解決策は、受信者が個人的な会議から公開鍵を取得することです... 2 の答えは日々変化する可能性がありますが、強制するのに費用がかかるものは、おそらく将来的に壊れるのが安くなるでしょう。 . その時までに、新しいアルゴリズムや拡大された鍵サイズが登場することを願っています。
もちろん。
最も簡単な方法は、ファイルを MD5 アルゴリズムで実行し、そのデータをファイル内に埋め込むことです。チェックサムを分割して、ファイルの既知のポイント (ファイルの部分サイズに基づいて、たとえば 30%、50%、75%) に配置して、それを非表示にすることができます。
同様に、ファイルを暗号化するか、ファイルの一部を (MD5 チェックサムと共に) 暗号化し、それをファイルに埋め込むことができます。 編集 チェックサムデータを使用する前に削除する必要があることを忘れていました。
もちろん、ファイルを別のプログラム (Word など) ですぐに読み取れるようにする必要がある場合は、ファイルを「破損」して読み取れないようにしたくないため、少し複雑になります。
もちろん可能ですが、その場合、ファイル全体の SHA ダイジェストは、含めた SHA にはなりません。これは暗号化ハッシュ関数であるため、ファイル内の 1 ビットを変更するとハッシュ全体が変更されるためです。探しているのは、一連の基準に一致するようにファイルの内容を使用して計算されたチェックサムです。