gitの使用中にハッシュの衝突があった場合、実際にはどうなりますか?
たとえば、同じsha1チェックサムで2つのファイルをコミットできた場合、gitがそれに気づくか、ファイルの1つを破損しますか?
それに合わせてgitを改善できますか、それとも新しいハッシュアルゴリズムに変更する必要がありますか?
(それがどれほどありそうもないことについて議論することによってこの質問をそらさないでください-ありがとう)
gitの使用中にハッシュの衝突があった場合、実際にはどうなりますか?
たとえば、同じsha1チェックサムで2つのファイルをコミットできた場合、gitがそれに気づくか、ファイルの1つを破損しますか?
それに合わせてgitを改善できますか、それとも新しいハッシュアルゴリズムに変更する必要がありますか?
(それがどれほどありそうもないことについて議論することによってこの質問をそらさないでください-ありがとう)
回答:
SHA-1ハッシュは、40の16進文字列です。つまり、1文字あたり4ビットに40 ... 160ビットを掛けたものです。これで、10ビットはおよそ1000(正確には1024)であることがわかります。これは、1 000 000 000 000 000 000 000 000 000 000 000 000 000 000異なるSHA-1ハッシュがあることを意味します... 10 48。
これに相当するものは何ですか?さて月は約10 47個の原子で構成されています。ですから、10個の月があるとします。これらの月の1つでランダムに1つの原子を選択します。次に、もう一度ランダムな原子を選択します。同じ原子を2回選択する可能性、与えられた2つのgitコミットが同じSHA-1ハッシュを持つ可能性です。
これを拡張して、私たちは質問をすることができます...
衝突の心配を始める前に、リポジトリにいくつのコミットが必要ですか?
これは、いわゆる「バースデーアタック」に関連します。これは、「バースデーパラドックス」または「バースデープロブレム」を指します。これは、特定のセットからランダムに選択した場合、驚くほど少ない数のピックが必要になる前に、何かを2回選んだ。しかし、「驚くほど少ない」というのは、ここでは非常に相対的な用語です。
ウィキペディアには、誕生日パラドックスの衝突の確率に関する表があります。40文字のハッシュのエントリはありません。しかし、32文字と48文字のエントリの補間により、衝突の0.1%の確率で5 * 10 22 gitコミットの範囲に到達します。これは、衝突が発生する確率が0.1%に達する前に、50兆億の異なるコミット、つまり50 ゼッタコミットです。
これらのコミットのハッシュだけのバイト合計は、1年間地球上で生成されたすべてのデータよりも多くのデータになります。つまり、YouTubeがビデオをストリーミングするよりも速くコードをチャーンする必要があります。頑張ってください。:D
これのポイントは、誰かが故意に衝突を引き起こしていない限り、ランダムに発生する確率は非常に小さいため、この問題を無視できるということです。
OK、ありそうもないことが起こった、または誰かが意図的にSHA-1ハッシュコリジョンを調整したと仮定します。次に何が起こりますか?
その場合、誰かがそれを実験した優れた答えがあります。その答えから引用します:
- 同じハッシュのblobがすでに存在する場合、警告はまったく表示されません。すべてが大丈夫なようですが、プッシュしたり、誰かがクローンを作成したり、元に戻したりすると、最新のバージョンが失われます(上記で説明したとおり)。
- ツリーオブジェクトがすでに存在し、同じハッシュでBLOBを作成する場合:プッシュするか、誰かがリポジトリを複製するまで、すべてが正常に見えます。次に、リポジトリが破損していることがわかります。
- commitオブジェクトがすでに存在し、同じハッシュでblobを作成する場合:#2と同じ-破損
- blobがすでに存在し、同じハッシュでcommitオブジェクトを作成すると、「ref」の更新時に失敗します。
- blobがすでに存在し、同じハッシュでツリーオブジェクトを作成する場合。コミットの作成時に失敗します。
- ツリーオブジェクトが既に存在し、同じハッシュでコミットオブジェクトを作成すると、「ref」の更新時に失敗します。
- ツリーオブジェクトがすでに存在していて、同じハッシュでツリーオブジェクトを作成した場合、すべてが問題ないように見えます。しかしコミットすると、すべてのリポジトリが間違ったツリーを参照します。
- コミットオブジェクトがすでに存在し、同じハッシュでコミットオブジェクトを作成した場合、すべてが正常に見えるようになります。ただし、コミットすると、コミットは作成されず、HEADポインタは古いコミットに移動します。
- コミットオブジェクトが既に存在し、同じハッシュでツリーオブジェクトを作成すると、コミットの作成時に失敗します。
思われるように、いくつかのケースは良くありません。特に、ケース#2と#3はリポジトリを混乱させます。ただし、障害はそのリポジトリ内にとどまり、攻撃/奇妙な可能性は他のリポジトリに伝播しないようです。
また、意図的な衝突の問題は実際の脅威として認識されているようで、たとえば、GitHubはそれを防ぐための対策を講じています。
2つのファイルがgitで同じハッシュサムを持っている場合、それらはそれらのファイルを同一として扱います。絶対に起こりそうもないケースでこれが発生した場合、いつでも1つのコミットに戻って、ファイル内の何かを変更して、もう衝突しないようにすることができます...
スレッド「sha-256について考え始めましたか?」のスレッドのLinus Torvaldsの投稿を参照してください。gitのメーリングリストで。
この質問に正しい「しかし」で答えることは、それが問題ではない理由を説明することなく実際には不可能です。ハッシュが実際に何であるかを十分に把握せずにそれを行うことは不可能です。これは、CSプログラムで遭遇した単純なケースよりも複雑です。
ここに情報理論の基本的な誤解があります。ある量(つまり、ハッシュ)を破棄して大量の情報をより小さな量に減らすと、データの長さに直接関係する衝突の可能性があります。データが短いほど、可能性は低くなります。これで、衝突の大部分は意味不明になり、実際に発生する可能性が高くなります(意味不明な内容をチェックインすることはありません...バイナリイメージが多少構造化されていても)。結局、チャンスは遠いです。あなたの質問に答えるために、はい、gitはそれらを同じように扱います、ハッシュアルゴリズムを変更することは助けにはなりません、それはある種の「2回目のチェック」を行いますが、結局、あなたは同じくらい多くの「追加のチェック」データが必要になりますデータの長さが100%確実であるように... 99.99999になることに注意してください... 桁数が非常に多い...確かに、あなたが説明するような簡単なチェックで。SHA-xは暗号学的に強力なハッシュです。つまり、通常、互いに非常に類似しており、同じハッシュを持つ2つのソースデータセットを意図的に作成することは難しくありません。データの1ビットの変更により、ハッシュ出力に複数(できればできるだけ多く)のビットの変更が作成されるはずです。これは、ハッシュから完全なセットに戻るのが非常に難しい(ただし、不可能ではない)ことを意味します。衝突し、それによってその衝突のセットから元のメッセージを引き出します-いくつかを除いてすべてが意味不明なものになり、メッセージの長さがかなりの長さである場合、ふるいにかける膨大な数はまだありません。暗号ハッシュの欠点は、一般的に計算が遅いことです。
では、Gitにとってそれはどういう意味ですか?あまりない。ハッシュが(他のすべてのものに比べて)非常にまれにしか実行されないため、演算全体の計算ペナルティは低くなります。衝突のペアに当たる可能性は非常に低いため、発生する可能性が低く、すぐに検出されない(つまり、コードが突然ビルドを停止する可能性が高い)ため、ユーザーは問題を修正できます(リビジョンのバックアップ、もう一度変更すると、時間の変更により、ほぼ確実に別のハッシュが取得されます。これにより、ハッシュもgitにフィードされます)。gitに任意のバイナリを格納している場合、それが実際の問題である可能性が高くなります。これは、主な使用モデルではありません。もしそれをしたいなら...おそらく伝統的なデータベースを使う方が良いでしょう。
これについて考えるのは間違いではありません。多くの人が「考えてみる価値がないとは考えにくい」とだけ言っているのは良い質問ですが、それは実際には少し複雑です。それが発生した場合、それは非常に容易に検出できるはずであり、通常のワークフローで静かに破損することはありません。
you'll almost certainly get a different hash because of the time change, which also feeds the hash in git
ハッシュはファイルの内容のみに基づいているのではないですか?
それに合わせてgitを改善できますか、それとも新しいハッシュアルゴリズムに変更する必要がありますか?
すべてのハッシュアルゴリズムで衝突が発生する可能性があるため、ハッシュ関数を変更しても問題は排除されず、発生する可能性が低くなります。だからあなたは本当に良いハッシュ関数を選ぶべきです(SHA-1はすでにありますが、言われないように頼みました:)
「GitはblobでのSHA-1衝突をどのように処理しますか?」で良い研究を見ることができます。
SHA1衝突が可能になったので(この回答でshattered.ioを参照しています)、Git 2.13(2017年第2四半期)がSHA-1実装の「衝突を作成する試みの検出」バリアントで現在の状況を改善/軽減することを知ってくださいMarc Stevens(CWI)とDan Shumow(Microsoft)による。
Jeff King()によるcommit f5f5e7f、commit 8325e43、commit c0c2006、commit 45a574e、commit 28dc98e(2017年3月16日)を参照してください。(合併によりJunio C浜野- -で48b3693コミットし、2017年3月24日)をpeff
gitster
Makefile
:DC_SHA1
デフォルトにする以前は、OpenSSLライブラリのSHA1実装をデフォルトで使用していました。
最近の「粉々になった」アナウンスの後で衝突攻撃に注意しようとしているので、代わりにDC_SHA1実装を使用するように人々を促すためにデフォルトを切り替えます。
OpenSSLからの実装を使用したい場合は、OPENSSL_SHA1=YesPlease
"make
"を実行するときに明示的に要求できます。実際にはGitオブジェクトの衝突はありません。そのため、最善の方法は、粉砕されたPDFの1つをtest-sha1で実行することです。これにより、衝突チェックがトリガーされ、終了します。
Gitをそれに合わせて改善できますか、それとも新しいハッシュアルゴリズムに変更する必要がありますか?
2017年12月にGit 2.16で更新(2018年第1四半期):代替SHAをサポートするためのこの取り組みが進行中です:「なぜGitはより最新のSHAを使用しないのですか?」を参照してください。」を。
別のハッシュアルゴリズムを使用できるようになります。SHA1がGitの唯一のアルゴリズムではなくなりました。
Git 2.18(2018年第2四半期)はそのプロセスを文書化しています。
参照5988eb6をコミットし、45fa195をコミットすることで(2018年3月26日)ÆvarアインホルトBjarmason( )avar
。
(合併によりJunio C浜野- gitster
-でコミットd877975、2018年4月11日)
文書
hash-function-transition
:SHAtteredの意味を明確にするSHAttered攻撃がGitで実際に何を意味するかを明確にしてください。
以前のバージョンのテキストでは、この特定の攻撃に対する緩和策がすでにGitにあることについては何も言及されていませんでした。SHAtteredの研究者はこれを解読衝突攻撃を検出すると主張しています。ニュアンスの一部が間違っている可能性がありますが、私の知る限り、この新しいテキストはgitでのSHA-1の現在の状況を正確に要約しています。つまり、gitは実際にはSHA-1を使用していません。Hardened-SHA-1を使用しています(たまたま、同じ出力99.99999999999 ...%の時間を生成します)。
したがって、前のテキストは次のことを主張する際に正しくありませんでした。
[...] [SHAttered]の結果として、SHA-1は暗号的に安全であるとはもう考えられません[...]
そうではありません。私たちは、粉々に対する緩和策を持っている、しかし、 私たちは仕事の方に移動することが賢明考える
NewHash
SHA-1または硬化-SHA-1のいずれかですべき将来の脆弱性が出てきます。
したがって、新しいドキュメントは次のようになります。
Git v2.13.0以降は、その後、デフォルトで強化されたSHA-1実装に移行しました。これは、SHAttered攻撃に対して脆弱ではありません。
したがって、Gitは事実上、SHA-1ではなく、その脆弱性を共有しない新しいハッシュにすでに移行しています。その新しいハッシュ関数は、SHAtteredによって発行された2つのPDFを除いて、すべての既知の入力に対してまったく同じ出力を生成します。研究者、およびそれらの研究者によって書かれた新しい実装は、将来の暗号解読衝突攻撃を検出すると主張しています
いずれにしても、SHA-1の亜種を通過して新しいハッシュに移動することは賢明と考えられています。SHA-1に対する今後の攻撃が今後公開されないという保証はなく、これらの攻撃は実行可能な緩和策を持たない可能性があります。
SHA-1とそのバリアントが本当に破壊されたとしたら、Gitのハッシュ関数は暗号的に安全であるとはもはや考えられません。特定のハッシュ値が、話者が意図した既知の適切なバージョンのコンテンツを表しているとは信じられないため、これはハッシュ値の通信に影響を与えます。
注:同じドキュメント(2018年第3四半期、Git 2.19)では、「新しいハッシュ」がSHA-256として明示的に参照されています。「なぜGitはより新しいSHAを使用しないのですか?」を参照してください。
Googleは現在、特定の前提条件の下でSHA-1の衝突が発生する可能性があると主張しています:https : //security.googleblog.com/2017/02/announcing-first-sha1-collision.html
gitはSHA-1を使用してファイルの整合性をチェックするため、これはgitのファイルの整合性が損なわれることを意味します。
IMO、gitは意図的な衝突が可能になったため、間違いなくより良いハッシュアルゴリズムを使用する必要があります。
ハッシュの衝突は非常に起こりそうにないので、それは全く心を吹き飛ばしています!世界中の科学者たちは、それを達成するために一生懸命に努力していますが、まだそれを管理していませんでした。ただし、MD5などの特定のアルゴリズムでは成功しました。
SHA-256には2 ^ 256の可能なハッシュがあります。それは約10 ^ 78です。またはよりグラフィックになるために、衝突の可能性は約です
1:100 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
宝くじ当選のチャンスは約1:14美緒です。SHA-256との衝突の可能性は、11日間連続で宝くじに当たるようなものです!
数学的な説明:14 000 000 ^ 11〜2 ^ 256
さらに、宇宙には約10 ^ 80の原子があります。これは、SHA-256の組み合わせよりも100倍多くなります。
MD5でさえ、可能性はごくわずかです。しかし、数学者はなんとか衝突を引き起こしました:
d131dd02c5e6eec4 693d9a0698aff95c 2fcab5 8 712467eab 4004583eb8fb7f89 55ad340609f4b302 83e4888325 7 1415a 085125e8f7cdc99f d91dbdf280373c5b d8823e3156348f5b ae6dacd436c919c6 dd53e2 b 487da03fd 02396306d248cda0 e99f33420f577ee8 ce54b67080 a 80d1e c69821bcb6a88393 96f965 2 b6ff72a70
と同じMD5を持っています
d131dd02c5e6eec4 693d9a0698aff95c 2fcab5 0 712467eab 4004583eb8fb7f89 55ad340609f4b302 83e4888325 f 1415a 085125e8f7cdc99f d91dbd7280373c5b d8823e3156348f5b ae6dacd436c919c6 dd53e2 3 487da03fd 02396306d248cda0 e99f33420f577ee8 ce54b67080 2 80d1e c69821bcb6a88393 96f965 a b6ff72a70
これは、アルゴリズムが解読されたためにMD5の安全性が低下したという意味ではありません。意図的にMD5衝突を作成することはできますが、偶発的なMD5衝突の可能性は2 ^ 128であり、これはまだ多くあります。
衝突を心配する必要はありません。ハッシュアルゴリズムは、ファイルの同一性をチェックする2番目に安全な方法です。安全な唯一の方法は、バイナリ比較です。
さて、これで何が起こるかはわかったと思います。リポジトリが破損することを期待する必要があります(ソース)。
最近、2013年4月29日の投稿をBSDディスカッショングループで見つけました。
http://openbsd-archive.7691.n7.nabble.com/Why-does-OpenBSD-use-CVS-td226952.html
ポスターが主張するところ:
git rebaseを使用して、ハッシュの衝突に一度遭遇しました。
残念ながら、彼は彼の主張の証拠を提供していません。しかし、多分あなたは彼に連絡して、この想定される事件について彼に尋ねようとすることを望みます。
しかし、より一般的なレベルでは、誕生日攻撃のため、SHA-1ハッシュの衝突の可能性はpow(2、80)で1です。
これは非常に聞こえ、確かに世界中のすべてのGitリポジトリに存在する個々のファイルのバージョンの総数よりもはるかに多くなります。
ただし、これは実際にバージョン履歴に残っているバージョンにのみ適用されます。
開発者がリベースに大きく依存している場合、ブランチに対してリベースが実行されるたびに、そのブランチのすべてのバージョン(またはブランチのリベースされた部分)のすべてのコミットが新しいハッシュを取得します。「git filter-branch」で変更されたすべてのファイルに同じことが当てはまります。したがって、「rebase」と「filter-branch」は、実際に保持されていなくても、時間の経過とともに生成されるハッシュの数の大きな乗数となる可能性があります。 )、元のブランチは破棄されます。
ただし、リベースまたはフィルターブランチ中に衝突が発生した場合でも、悪影響が生じる可能性があります。
もう1つは、gitリポジトリ内のハッシュされたエンティティの総数を見積もり、それらがpow(2、80)からどれだけ離れているかを確認することです。
私たちには約80億人がいて、それらすべてがgitを実行していて、1人あたり100のgitリポジトリでバージョンを管理しているとします。さらに、平均的なリポジトリには100のコミットと10のファイルがあり、コミットごとにこれらのファイルの1つだけが変更されると仮定します。
リビジョンごとに、少なくともツリーオブジェクトとコミットオブジェクト自体のハッシュがあります。変更されたファイルと合わせて、リビジョンごとに3つのハッシュがあり、リポジトリごとに300のハッシュがあります。
80億人の100のリポジトリーの場合、これはpow(2、47)を提供しますが、これはまだpow(2、80)とはかけ離れています。
ただし、この推定にどのように含めるかは不明であるため、これには上記の想定される乗算効果は含まれていません。多分それは衝突の可能性をかなり増加させる可能性があります。特に、長いコミット履歴(Linuxカーネルなど)を持つ非常に大規模なリポジトリが、小さな変更のために多くの人によってリベースされている場合でも、影響を受けるすべてのコミットに対して異なるハッシュが作成されます。
I've been informed by the git Gods that the chances of a SHA1 collision is the same as the Earth being sucked up into the black hole created by the CERN accelerator. If this is indeed true, then there's no need for that extra memcmp.
、ソース:lwn.net/Articles/307281