web-dev-qa-db-ja.com

2つのハッシュを比較することで、変更の大きさを知ることができますか?

ハッシュ関数は一方向の関数であり、ハッシュの変更は、元のデータが変更された(データ全体にわずかな変更を加えてもハッシュ全体が変更された)ことを示していると思います。

しかし、2つのハッシュが異なる場合に元のデータがどの程度変更されたかを知る方法はありますか?

48
Maria Ahmed

いいえ、少なくとも良いハッシュ関数があれば。

特定のデータセットに対してハッシュを作成し、次に別のデータセットに対して変更されたハッシュを作成することにより、これを自分でテストできます。結果のハッシュ関数のすべてのビットが、約50%の確率でフリップすることがわかります。

文字列MechMK1のSHA-256ハッシュを作成して、これを示します。

$ echo -n "MechMK1" | sha256sum
2c31be311a0deeab37245d9a98219521fb36edd8bcd305e9de8b31da76e1ddd9

これをバイナリに変換すると、次の結果が得られます。

00101100 00110001 10111110 00110001 00011010 00001101 11101110 10101011
00110111 00100100 01011101 10011010 10011000 00100001 10010101 00100001
11111011 00110110 11101101 11011000 10111100 11010011 00000101 11101001
11011110 10001011 00110001 11011010 01110110 11100001 11011101 11011001

次に、文字列MechMK3のSHA-256ハッシュを計算します。これにより、入力の1ビットが変更されます。

$ echo -n "MechMK3" | sha256sum
3797dec3453ee07e60f8cf343edb7643cecffcf0af847a73ff2a1912535433cd

再度バイナリに変換すると、次の結果が得られます。

00110111 10010111 11011110 11000011 01000101 00111110 11100000 01111110
01100000 11111000 11001111 00110100 00111110 11011011 01110110 01000011
11001110 11001111 11111100 11110000 10101111 10000100 01111010 01110011
11111111 00101010 00011001 00010010 01010011 01010100 00110011 11001101

両方の結果を比較し、ビットが両方のハッシュと異なる頻度、およびすべてのビットの正確に128または50%が異なる頻度を確認しました。これを自分で試し、どのような結果が得られるかを確認したい場合は、 単純なCプログラム を作成しました。

93
MechMK1

TL:DR;暗号化ハッシュ関数; 2つの異なるメッセージのハッシュは、統計的に独立しているように見えるはずです。$


ハッシュは一方向の関数であり、ハッシュの変更は、元のデータが変更された(データ全体にわずかな変更を加えてもハッシュ全体が変更される)ことを通知するためのものであることがわかりました。

Avalanche Criteria は、一方向であるだけでなく、優れた暗号化ハッシュ関数に求められるものでもあります。

  • 入力の単一ビットの変更により、50%の確率で各出力ビットが変更されます。

  • 複数のビットの変更:これは少しトリッキーです、ハッシュ関数アーカイブが random Oracleモデルに従って疑似ランダム関数をモデル化することを検討する場合 次に、各入力ビットの変化を平均で50%と見なすことができます。これは、ビットがどれだけ変化したかは関係ありません。

    これは、ビットを1つ考慮し、ヘッドがフリップした場合とテールが来た場合にコインをフリップすることで確認でき、フリップの50%はフリップしません。今、別のコインを投げて、同じことをします。結果は同じです(簡単な数学)。

    もちろん、ランダムなOracleモデルを実現することはできません。したがって、出力ビットは互いに独立していません。それらは、識別器を見つけることができる限り長く見え、それはハッシュ関数に対する解読攻撃を構成します。優れた暗号化ハッシュ関数が見つかると、それがニュースに表示されます。

ハッシュ関数に雪崩基準があることを証明することは、多くのランダムな入力値をテストする必要がある統計プロセスです。すべての入力とビット補数によってビットの半分が変更されるわけではなく、これは予期される動作ではありません。また、出力ビットがランダムに変更されることを示す必要があります。

満たされていない場合、このハッシュ関数は、プリイメージ耐性、2番目のプリイメージ耐性、および衝突耐性を満たさない可能性があります。 *

  • preimage-resistance—本質的にすべての事前に指定された出力の場合、その出力にハッシュする入力を見つけること、つまり任意の事前画像を見つけることは計算上実行不可能です_x'_このようなh(x') = yは、対応する入力が不明なyが指定された場合に発生します。
  • 2番目のプリイメージの抵抗、弱い衝突—指定された入力と同じ出力を持つ、つまりxが指定された2番目の入力を見つけることは計算上実行不可能です、2番目のプリイメージ_x' != x_を見つけるには、h(x) = h(x')を使用します。
  • 衝突抵抗、strong-collision—同じ出力にハッシュする2つの異なる入力x、_x'_を見つけることは計算上実行不可能です。つまり、 、そのようなh(x) = h(x')

それぞれの失敗は攻撃を引き起こす可能性があり、それが成功した場合、これは壊滅的になる可能性があります。例;誰かがあなたの元のメッセージに対して同じ価値を持つ2番目のメッセージ(またはLinux CD ISOのハッシュ)を見つけたと考えてください。

_This is a signed message representing the payment is $1.00, have a Nice day
I will pay you $1,000,000.00 have a Nice day
_

うまくいけば、SHA-1とMD5でさえこの攻撃に抵抗しているでしょう。したがって、ハッシュ値が変更された場合、データに変更があると想定できます。ランダムなテキストがあなたの値と同じハッシュを持つ確率は無視できます。

しかし、2つのハッシュが異なる場合に元のデータがどの程度変更されたかを知る方法はありますか?

うまくいけば、。巧妙な攻撃者が使用できる変更に関する情報を提供する単一のバイアスがある場合。


*これは正式な定義であり、Rogaway氏とShrimpton氏の独創的な論文から引用されたものです 暗号化ハッシュ関数の基本:...

$簡素化してくれたFutureSecurityに感謝

37
kelalaka

他の回答ですでに述べたように、 暗号化ハッシュ関数 の場合、回答は「いいえ」です。これらは一般に、完全にランダムな関数のように動作するように設計されており、類似の入力に対して生成されたハッシュ出力の検出可能な類似性により、ハッシュをランダム関数から区別することもできます。*

ただし、areローカリティ依存ハッシュ などの他の種類のハッシュ関数があり、少なくとも「はい、ときどき」である可能性があります。

特に、局所性に敏感なハッシュは、通常、「いくつかの類似性メトリックに従って最大でδだけ異なる2つの入力は、確率p> 0で、最大でεδ)異なる他の(場合によっては同じ)類似性メトリックによって異なります。 "通常、ハッシュの距離メトリックは Hamming distance のようになりますが、入力に対応するメトリックは、たとえば 距離を編集 。局所性に敏感な適切なハッシュ関数の選択は、主に、関心のある特定の距離メトリックに依存します。


*)技術的には、安全な暗号化ハッシュの古典的な定義では 衝突抵抗 と最初と2番目の プリイメージ抵抗 のみが必要です。 proveへの明白な方法はありません。ハッシュ関数はこれらのプロパティを持つことができず、何らかの方法で局所性の影響を受けやすいことはわかりませんが、かなり重要な制約を課しています。特に、特定のハッシュ出力からεδ)の距離内にあるハッシュ出力の数[〜#〜] h [〜#〜]x)は、距離内の他の入力数よりも速く成長する必要がありますδ対応する入力のx適切な値の場合δの場合、他の同様の入力を単にテストすると、衝突が発生する可能性が非常に高いためです。いずれにせよ、この暗号化セキュリティのより弱い定義でさえ、局所性の影響を受けやすいハッシュ関数に気づいておらず、そのようなハッシュが存在する場合にどのように見えるかもわかりません。

30
Ilmari Karonen

これが可能かもしれないハッシュタイプがあると私は確信していますが、暗号的に安全なハッシュのポイントは、それが起こらないことを確認することです。ハッシュの出力の変更に基づいて、メッセージの変更について推測や推論を行うことはできません。

暗号化アナリストはこれを Avalanche Effectで測定します。 強いハッシュは、入力に小さな変更が加えられた場合でも、出力に大きな変更を加える必要があります。

17
schroeder

はい、ただし、ssdeep https://ssdeep-project.github.io/ssdeep/index.html などのファジーハッシュと、ファイル間の類似性を測定するために特別に設計されたもの、および特定のimphashなどの変更を含まないファイルの部分 https://www.fireeye.com/blog/threat-research/2014/01/tracking-malware-import-hashing.html 。質問へのコメントで言及されている他の種類のハッシュがありますが、私はそれら、それらのプロパティ、および使用法に精通していないので、ここではそれらに触れません。私がカバーしなかった他のタイプのハッシュがある場合は、この回答に遠慮なく追加してください。

類似性を追跡するように設計されているか、入力全体をカバーしていない特殊なハッシュの外では、この投稿に対するkelalakaまたはMechMK1の答えはノーです。私が説明した関数は真のハッシュ関数ではない可能性がありますが、私のコミュニティではハッシュ関数と呼ばれています。

10
solumnant

強力なハッシュ関数は、小さな変更で出力ハッシュに大きな違いをもたらすはずです。つまり、2つの値の違いを確認したい場合は、ハミング距離アルゴリズムを使用できます。

https://en.wikipedia.org/wiki/Hamming_distance

4
James Kirkby

できますが、それは純粋にハッシュ関数ではありません。

エラー修正コード はハッシュ関数の一種であり、メッセージの一部の変更を検出できるだけでなく、それらの変更を修正することもできます。もちろん、変更はある程度のエラーに対してのみ修正できます。一般に、エラー修正コードがメッセージに対して相対的であるほど、検出および修正できる変更が多くなります。

エラー修正コードは、変更を修正するこの機能のために最適化されています。つまり、変更を修正できないメッセージへの変更を検出するのに最適ではない可能性があります。これらは主に、再送信が簡単にできないメッセージのハッシュとして意図されているため、元のメッセージの回復が優先されます。また、メッセージに対する意図的な攻撃は発生しないと想定しています。

暗号化ハッシュ、またはCRCなどのより安全性の低いハッシュは、異なる動作をする傾向があります。通常、これらは、障害のあるメッセージの再送信を要求できる状況、または意図的な攻撃のリスクがあり、障害のあるメッセージを確実に検出して拒否する必要がある場合に使用されます。これらは常に一方向関数であり、それらが「一方向」である度合いは、それらがどれほど堅牢であるかを示します。以前の回答で述べたように、優れた暗号化ハッシュは、元のメッセージに関する情報を提供しません。

1
Graham

ハッシュは常に意味するわけではない暗号化ハッシュ

目的に固有のハッシュ関数を作成できます。

ファイルをバイトごとに比較し、相違ごとにハッシュを増分することを検討してください。長さの違いを追加します。これは、差異の程度に直接関係する一方向の計算を提供するハッシュ関数です。

よりインテリジェントなハッシュ関数が必要な場合は、「diff file1 file2 | wc -l」を試してください。

0
cmm