Gitがより最新のSHAを使用しないのはなぜですか?


90

GitがリビジョンのIDとしてSHA-1ダイジェストを使用することを読みました。SHAの最新バージョンを使用しないのはなぜですか?


2
私が考えることができる唯一の理由はパフォーマンスです。SHA-1はSHA-2よりも高速です。個人的には、SHA-1の衝突抵抗はかなり弱いので、それは悪い決断だと思います。
CodesInChaos 2015年

4
stackoverflow.com/questions/9392365/…-完全に一致するわけではありませんが、同様の範囲をカバーします
ソフトウェア

6
これは2006年にgitメーリングリストで議論されました。スレッド全体を参照してください。要約すると、Linusは当時、SHA-1は衝突が発生しないように十分に一意である必要があるだけであると言っていました。SHA-1はgitのセキュリティ機能ではありません。「信頼できないソースからのデータを盲目的に受け入れるだけの人は、ハッシュ攻撃がレーダーにさえ及ばないほど多くの他の方法でねじ込まれています。」- ライナス
TBC0

28
更新:SHA-1の衝突が
荒れ果てた

2
2018年第1四半期:代替SHAをサポートするこの取り組みが進行中です。以下の私の回答を
VonC '15

回答:


62

SHAの最新バージョンを使用しないのはなぜですか?

2017年12月:予定されています。そして、Git 2.16(2018年第1四半期)は、その意図を説明および実装する最初のリリースです。

注:以下のGit 2.19を参照してください:SHA-256になります。

Git 2.16は、Gitで使用されるハッシュ関数を定義するためのインフラストラクチャを提案し、さまざまなコードパス全体にそれを組み込むための取り組みを開始します。

Ramsay Jones( ``)によるcommit c250e02(2017年11月28日)を参照してください。commit eb0ccfdcommit 78a6766commit f50e766commit abade65(2017年11月12日)のbrian mを 参照してくださいカールソン((合併によりJunio C浜野- -721cc43コミットし、2017年12月13日)を
bk2204
gitster


ハッシュアルゴリズムを表す構造を追加

将来的には追加のハッシュアルゴリズムをサポートする必要があるため、ハッシュアルゴリズムとそれに伴うすべてのデータを表す構造を追加します定数を
追加して、ハッシュアルゴリズムを簡単に列挙できるようにします。任意のハッシュアルゴリズムで使用できる抽象APIを作成する関数
実装し、このAPIに準拠する既存のSHA1関数のラッパーを実装します。typedefs

16進サイズとバイナリサイズの値を公開します
一方は常に他方の2倍になりますが、2つの値はどちらもコードベース全体で非常に一般的に使用され、読みやすさの向上につながります。

nullオブジェクトIDのエントリをハッシュアルゴリズム構造に含めないでください。
この値はすべてゼロであるため、適切なサイズのすべてゼロのオブジェクトIDを使用でき、ハッシュごとに特定のオブジェクトIDを格納する必要はありません。

現在のハッシュ関数遷移計画では、SHA-1またはNewHash形式のユーザーからの入力を受け入れる時期を想定しています。
ユーザーが提供したものを知ることができないため、不明なアルゴリズム表す定数を追加して、正しい値を調べる必要があることを示すことができるようにします。


ハッシュアルゴリズムサポートとリポジトリ設定を統合する

Gitの将来のバージョンでは、追加のハッシュアルゴリズムをサポートする予定です。
ハッシュアルゴリズムの列挙をリポジトリ設定と統合し、列挙されたデータへのポインタをstruct repositoryに格納します
もちろん、現在サポートされているのはSHA-1だけなので、この値をにハードコードします read_repository_format
将来的には、この値を構成から列挙する予定です。

リポジトリグローバルの構造ポインタを指す定数the_hash_algoを追加hash_algoします。
これは、データをディスクにシリアル化するために使用されるハッシュであり、ユーザーにアイテムを表示するために使用されるハッシュではないことに注意してください。
移行計画では、これらが異なる可能性があると予想しています。このケースに対応するため
に、将来、要素を追加することができます(たとえば、ui_hash_algo)。


2018年8月の更新、Git 2.19(2018年第3四半期)では、GitはSHA-256をNewHashとして選択しているようです。

Jonathan Nieder()によるcommit 0ed8d8d(2018年8月4日)を参照してください。 参照してください13f5e09コミットにより(2018年7月25日)をÆvarアインホルトBjarmason( ) (合併によりJunio C浜野- -34f2297コミットし、2018年8月20日)をartagnon
avar
gitster

dochash-function-transition:NewHashとしてSHA-256を選択します

セキュリティの観点から、SHA-256、BLAKE2、SHA3-256、K12などはすべて同様のセキュリティプロパティを持つと考えられています。
セキュリティの観点からは、いずれも優れたオプションです。

SHA-256には多くの利点があります。

  • それはしばらくの間存在し、広く使用されており、ほぼすべての単一の暗号ライブラリ(OpenSSL、mbedTLS、CryptoNG、SecureTransportなど)によってサポートされています。

  • SHA1DCと比較すると、ほとんどのベクトル化されたSHA-256実装は、加速なしでも実際には高速です。

  • OpenPGP(または、おそらくCMS)で署名を行う場合は、SHA-2を使用するため、どちらか一方の場合に2つの別々のアルゴリズムにセキュリティを依存させるのは意味がありません。 1つに頼るだけでセキュリティが壊れる可能性があります。

だからSHA-256です
ハッシュ関数遷移の設計ドキュメントを更新して、そのようにします。

このパッチの後NewHash、2008からの変数名 t/t9700/test.plとしての無関係な使用を除いて、文字列 " "のインスタンスは残りません。


Git 2.20(2018年第4四半期)でSHA 256への移行が進行中です。

参照0d7c419コミットdda6346コミットeccb5a5コミット93eb00fコミットd8a3a69コミットfbd0e37コミットf690b6bコミット49d1660コミット268babdコミットfa13080コミット7b5e614コミット58ce21bコミット2f0c9e9コミット825544aをコミットすることにより(2018年10月15日)ブライアンM 。カールソン(bk2204
参照してください6afedbaコミットにより(2018年10月15日)をSZEDERガーボル(szeder
(に合併Junio C浜野- gitster-d829d49をコミットし、2018年10月30日)

ハードコードされた定数を置き換える

参照を持ついくつかの40ベースの定数交換するGIT_MAX_HEXSZか、 the_hash_algo必要に応じてを。
のすべての使用法GIT_SHA1_HEXSZを使用するthe_hash_algoように変換して、特定のハッシュ長に適切になるようにします。
16進数のオブジェクトIDのサイズにハードコードされた定数を使用する代わりにparse_oid_hex、解析されたオブジェクトIDの後のそのポイントから計算されたポインターを使用するように切り替えます。

GIT_SHA1_HEXSZさらに削除/ Git 2.22(2019年第2四半期)に置き換えられ、d4e568bコミットします


この移行はGit 2.21(2019年第1四半期)でも継続され、sha-256ハッシュが追加されてコードにプラグインされ、「NewHash」でGitを構築できるようになります。

参照4b4e291コミット27dc04cコミット13eeedbコミットc166599をコミット37649b7コミットa2ce0a7コミット50c817eコミット9a3a0ffコミット0dab712コミット47edb64コミット(2018年11月14)、及び2f90b9dコミット1ccf07cをコミットすることにより(2018年10月22日)のブライアン・M 。カールソン(bk2204
(による合併Junio C浜野- gitster-33e4ae9コミット、2019年1月29日)を

SHA-256サポートの基本実装を追加します(2019年2月)

SHA-1は脆弱で、新しいハッシュ関数に移行する必要があります。
しばらくの間、この新しい関数をと呼びましたNewHash
最近、SHA-256をとして選択NewHashすることにしました
SHA-256の選択の背後にある理由は、このスレッドと、ハッシュ関数遷移ドキュメントのコミット履歴で概説されています

libtomcryptパブリックドメインにあるSHA-256ベースのoffの基本的な実装を追加します。
それを最適化し、コーディング基準を満たすように再構成します。
すべてのコンパイラでこれらの関数が正しく機能していることがわかっているため、SHA-1ブロック実装から更新関数と最終関数を取り込みます。この実装はSHA-1よりも低速ですが、よりパフォーマンスの高い実装が将来のコミットで導入される予定です。

ハッシュアルゴリズムのリストでSHA-256を結び、アルゴリズムが正しく機能することをテストを追加します。

このパッチでは、GitでSHA-256を使用するように切り替えることはまだできないことに注意してください。
より大きなハッシュアルゴリズムを処理するコードを準備するには、追加のパッチが必要であり、さらにテストの修正が必要です。

hash:OpenSSLを使用してSHA-256実装を追加する

SHA-1で使用できるOpenSSLルーチンがすでにあるので、SHA-256のルーチンも追加します。

Core i7-6600Uでは、このSHA-256実装はSHA1DC SHA-1実装と比べて遜色ありません。

SHA-1: 157 MiB/s (64 byte chunks); 337 MiB/s (16 KiB chunks)
SHA-256: 165 MiB/s (64 byte chunks); 408 MiB/s (16 KiB chunks)

sha256:を使用してSHA-256実装を追加する libgcrypt

一般に、アセンブリで作成された暗号化ルーチンはCよりもパフォーマンスが良く、これはSHA-256にも当てはまります。
さらに、ほとんどのLinuxディストリビューションは、ライセンス上の理由からOpenSSLにリンクされたGitを配布できません。

GnuPG libgcryptの依存関係であるため、GnuPGを備えたほとんどのシステムにもがあります。
libgcrypt数KiB以上のメッセージについては、SHA1DC実装よりも高速です。

比較のため、Core i7-6600Uでは、この実装は355 MiB /秒で16 KiBチャンクを処理し、SHA1DCは337 MiB /秒で同等のチャンクを処理します。

さらに、libgcryptはLGPL 2.1の下でライセンスされ、GPLと互換性があります。libgcryptを使用するSHA-256の実装を追加します。


アップグレード作業はGit 2.24(2019年第4四半期)でも継続されます。

参照aaa95dfをコミットしbe8e172をコミットし3f34d70をコミットしfc06be3をコミットし69fa337をコミットし3a4d7aaをコミットしe0cb7cdコミット8d4d86bコミットf6ca67dコミットdd336a5コミット894c0f6をコミットし4439c7aコミット95518faをコミットしe84f357をコミットしfe9fec4コミット976ff7eをコミットしコミット703d2d4コミット9d958ccコミット7962e04コミット料金4930(2019年8月18日)by brian m。カールソン(bk2204
(合併によりJunio C浜野- gitster-676278fコミットし、2019年10月11日)

GIT_SHA1_HEXSZハードコードされた定数を使用する代わりに、を使用するように切り替えthe_hash_algoます。


Git 2.26(2020年第1四半期)では、オブジェクト名がSHA-256を使用する日のテストスクリプトが準備されています。

参照277eb5aをコミットし44b6c05をコミットし7a868c5をコミットし1b8f39fコミットa8c17e3コミット8320722をコミットし74ad99bコミットba1be1aをコミットしcba472dをコミットし82d5aebをコミットしコミット3c5e65c235d3cdをコミットし1d86c8fコミット525a7f1をコミットし7a1bcb2をコミットしcb78f4fをコミットしコミット717c939コミット08a9dd8コミット215b60bコミット194264c(2019年12月21日)by brian m。カールソン(bk2204
(合併によりJunio C浜野- gitster-f52ab33をコミットする、2020年2月5日)

例:

t4204:ハッシュサイズを独立させる

サインオフ:brian m。カールソン

$OID_REGEXハードコードされた正規表現の代わりに使用します。

だから、代わりに:

grep "^[a-f0-9]\{40\} $(git rev-parse HEAD)$" output

テストが使用しています

grep "^$OID_REGEX $(git rev-parse HEAD)$" output

そしてOID_REGEXから来bdee9cdコミットにより(2018年5月13日)のブライアンメートル。カールソン(bk2204
(合併によりJunio C浜野- gitster-9472b13をコミットする、2018年5月30日、Gitのv2.18.0-RC0)

t/test-lib: 導入する OID_REGEX

サインオフ:brian m。カールソン

現在、変数があります。$_x40,これには、完全な40文字の16進定数に一致する正規表現が含まれています。

ただし、ではNewHash、40文字を超えるオブジェクトIDが使用されます。

そのような場合、$_x40紛らわしい名前になります。

を作成する $OID_REGEX現在のハッシュの長さに関係なく、適切なオブジェクトIDに一致する正規表現を常に反映変数をます。

そして、まだテストのために:

参照f303765をコミットしedf0424をコミットし5db24dcコミットd341e08をコミットし88ed241をコミットし48c10ccコミットf7ae8e6をコミットしe70649bコミットa30f93bをコミットしa79eec2コミット796d138をコミットし417e45eをコミットしdfa5f53をコミットしf743e8fをコミットし72f936bコミット5df0f11をコミットしコミット07877f3、6025e89コミット、db12505コミット7b1a182コミット94db7e3コミットdb12505(07 Feb 2020)by brian m。カールソン(bk2204
(合併によりJunio C浜野- gitster-コミット5af345a、2020年2月17日)

t5703:SHA-256でテストを機能させる

サインオフ:brian m。カールソン

このテストでは、長さが40桁の16進数文字のオブジェクトIDを使用したため、SHA-256をハッシュとして実行すると、テストがパスするだけでなく、ハングしました。

test_oid_initおよびを使用して、この値を固定のダミーオブジェクトIDに変更しますtest_oid

さらに、固定長ではなくフィールドでのカットを使用して、適切な長さのオブジェクトIDを抽出するようにしてください。


一部のコードパスには、リポジトリで動作するパラメータとしてリポジトリインスタンスが指定されていますが、渡されました the_repositoryされていましたが、インスタンスがその呼び出し先にれました。

参照b98d188コミット2dcde20をコミットし7ad5c44コミットc8123e7をコミットし5ec9b8aをコミットしa651946コミットeb999b3をコミットすることで(2020年1月30日)マテウスタバレス(matheustavares
(合併によりJunio C浜野- gitster-78e67cdをコミットする、2020年2月14日)を

sha1-filecheck_object_signature()任意のリポジトリを処理できるようにする

サインオフ:Matheus Tavares

の一部の呼び出し元はcheck_object_signature()任意のリポジトリで作業できますが、リポジトリはこの関数に渡されません。代わりに、the_repository常に内部的に使用されます。
起こり得る不整合を修正するには、関数が構造体リポジトリを受信し、それらの呼び出し元が処理されているリポジトリを渡すようにします。

に基づく:

sha1-file:合格git_hash_algohash_object_file()

サインオフ:Matheus Tavares

パラメータをhash_object_file()導入するgit_hash_algoことにより、任意のリポジトリで作業できるようにします。スコープ内にstructリポジトリポインターを持つ呼び出し元をgit_hash_algo、上記のリポジトリから渡すように変更します。
他のすべての呼び出し元については、で渡しますthe_hash_algo。これは、すでにで内部的に使用されていましたhash_object_file()
この機能は、次のパッチcheck_object_signature()で任意のリポジトリで機能できるようにするために使用されます(次に、object.c:parse_object()での不整合を修正するために使用されます)。


1
さらに、Git v2.13.0以降がデフォルトで強化されたSHA-1実装に移行したことを忘れないでください。これはSHAttered攻撃に対して脆弱ではありません。stackoverflow.com/a/43355918/6309を
VonC

1:Googleは2017年2月に衝突shattered.ioを作成しました(推定コスト$ 110,000)2:Nanyang Technological Universityは 2019年1月に衝突sha-mbles.github.ioを作成しました(推定コストは$ 11k-$ 45kです) GitがSHA1を通過する
bristweb

@bristweb「GitがSHA1を通過する時がきた」:私は同意し、Git 2.25(本日リリース)では、その動作は1つになります。git rev-parse使用するハッシュを出力できるようになりました:stackoverflow.com/a/58862319/6309。そして、空の木は、新たなSHA2 IDを持っている:stackoverflow.com/a/9766506/6309
VonC

このハッシュアルゴの拡張性により、CRC32はついに再び輝きます。
ウォルフ

52

更新:上記の質問とこの回答は2015年からのものです。それ以降、Googleは最初のSHA-1衝突を発表しました:https : //security.googleblog.com/2017/02/announcing-first-sha1-collision.html


明らかに、GitがSHA-1を使用し続ける理由について外部からのみ推測することができますが、これらが理由の1つである可能性があります。

  1. GitはLinus Torvaldが作成したものであり、Linusは現時点では明らかにSHA-1を別のハッシュアルゴリズムに置き換えたくないようです。
  2. 彼は、Gitに対するSHA-1の衝突ベースの攻撃の成功は、衝突自体を達成するよりもかなり難しく、SHA-1は本来あるべきよりも弱く、完全に壊れているわけではないため、少なくとも今日は実行可能な攻撃。さらに、衝突したオブジェクトが既存のオブジェクトよりも後に到着した場合、「成功した」攻撃はほとんど効果がなく、後者は有効なオブジェクトと同じであると見なされて無視されるため、逆が発生する可能性があります)。
  3. 特に移行が必要な既存のプロトコルに基づく既存のインフラストラクチャとデータがある場合、ソフトウェアの変更は時間がかかり、エラーが発生しやすくなります。暗号化セキュリティがシステムの唯一のポイントであるソフトウェアおよびハードウェア製品を製造する人々でさえ、SHA-1および他の弱いアルゴリズムから離れた場所に移行するプロセスが進行中です。ハードコーディングされたものをすべて想像してくださいunsigned char[20]すべてのバッファを ;-)、後で改造するよりも、最初から暗号化の俊敏性をプログラムする方がはるかに簡単です。
  4. SHA-1のパフォーマンスは、さまざまなSHA-2ハッシュよりも優れており(おそらく、今では契約を破るほどではありませんが、おそらく10年前の問題でした)、SHA-2のストレージサイズは大きくなっています。 。

いくつかのリンク:

私の個人的な見解では、実際の攻撃はおそらくしばらく休みですが、実際に攻撃が発生したとしても、ハッシュアルゴリズム自体を変更する以外の手段でおそらく最初に攻撃を軽減するでしょう。攻撃者の機能も一方向にしか機能しないため、アルゴリズムの選択に注意を払い、継続的にセキュリティ強度を上方修正しているため、Gitをロールモデルとして、特にその目的として採用することは賢明ではありません。 SHA-1の使用は、暗号化セキュリティであるとは主張していません。


7
「悪意のある人がいる可能性があります。彼らは成功しないでしょう。純粋に整合性チェックです。」-Linus Torvalds
Shakti

9
Gitのハッシュは、何かを検証するために人々がコードに付けた安全な署名のために安全である必要があります。これらの署名は、これらのハッシュの巨大なツリーに署名します。そのツリーの一部のブランチが衝突すると、署名が通過する間に悪意のあるコードが挿入される可能性があります。現在、Gitは信じられないほど広く使用されています。ハッシュのアップグレードが必要です。
fuzzyTew 2017

「粉々になった」という観点から考慮すべき2つのこと:1. SHA-1の使用。-SHA-1は、偶発的な破損をチェックするための栄光のあるチェックサムとして使用されます。-SHA-1は、コンテンツアドレス可能なストア内のオブジェクトを指定する(やや小さい)便利な16進数を与えるジェネレータ関数として使用されます(つまり、栄光のあるファイル名ジェネレータ)。- セキュリティに責任ある署名済みのコミット(つまり、公開鍵暗号のシグナチャ。sha-1ではない)
DrYak

2.実現可能性-膨大なGPU時間の後、Googleはペアのブロックシリーズを生成することに成功しました。-両方が同じSHA-1の合計にハッシュします(これが衝突です)-それらは完全に悪質です(コミットがバイナリジャンクの巨大なブロックを途中で持っている理由を正当化するのは難しいでしょう)。-粉々になったデモは、ランダムなバイナリジャンクのどれが存在するかに応じて、異なる動作を提示する方法に依存しています。これはPDF(埋め込みスクリプト言語が隠されている)で可能です。プレーンソース(
Underhanded

@DrYak For 2:コメントフィールドが含まれているフォトショップドキュメントを追跡しているとします。または、メタタグを含む他のメディアファイル。それはゲーム開発の典型的なケースです。ただし、通常、変更ごとにチェックされるわけではありません。コミットメッセージに「optimize for size」と表示されているのに、なぜメタタグをチェックするのでしょうか。
Arne Babenhauserheide 2017

5

これはMercurialのSHA1からの移行の緊急性に関する議論ですが、Gitにも適用されます:https : //www.mercurial-scm.org/wiki/mpm/SHA1

要するに、あなたが今日非常に精通していなければ、sha1よりもはるかに悪い脆弱性があります。それにもかかわらず、Mercurialはsha1からの移行に備えるために10年以上前に開始しました。

Mercurialのデータ構造とプロトコルをSHA1の後継機に組み込むための作業が何年も前から行われています。10年以上前のMercurial 0.9では、RevlogNGの導入により、revlog構造のより大きなハッシュにストレージスペースが割り当てられました。最近導入されたbundle2フォーマットは、ネットワーク上での異なるハッシュタイプの交換をサポートしています。残りの部分は、置換関数の選択と後方互換性戦略の選択だけです。

Mercurialが移行する前にgitがsha1から移行しない場合は、hg-gitを使用してローカルのMercurialミラーを維持することにより、常に別のレベルのセキュリティを追加できます。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.