Git 3.0でSHA-256がデフォルトに?それは大きな代償を伴う「失敗」になるかもしれない
Git 3.0's upcoming SHA-256 default will be a costly mistake
Git 3.0's upcoming SHA-256 default will be a costly mistake
Git 3.0において、ハッシュアルゴリズムをSHA-1からSHA-256へデフォルトで移行する動きがありますが、これには懸念が示されています。現在のエコシステムにおける広範な互換性や、移行に伴うパフォーマンス上のコストを考慮すると、この決定はプロジェクトにとって大きなリスク、あるいは多大なコストを強いる失敗に終わる可能性があります。
読んでみた感じ、GitにおけるSHA256の移行はIPv6の二の舞になりそうな兆候だらけだね。特に:
なぜGitがSHA-1とSHA-256のモードをもっと相互運用しやすくしないのか理解できないな。
SHA-1ハッシュのオブジェクトがSHA-256ハッシュのオブジェクトを参照できるようにすべきだ。あまり意味はないかもしれないけど。
それだけでなく、SHA-256ハッシュのオブジェクトもSHA-1ハッシュのオブジェクトを参照できるようにすべきだ。ただし大きな注意点がある。もしそれらのオブジェクト自体が衝突ペアの一部だった場合、それは正真正銘の問題になる。でも、これは回避可能だよ!例えばLinuxがSHA-256への移行を決定したとしよう。アップストリームプロジェクトで2027年1月1日と3月1日という2つの日付を決める。最初の期限までは、リポジトリに未登録だけど将来的に提出するかもしれないオブジェクトのハッシュをメンテナーが提出できるようにする。その期限でアップストリームツリーはリストを確定させ、リポジトリ内で参照できるようにする(このための新しい仕組みで)。2つ目の日付から、リポジトリはSHA-256のコミットのみを発行するようになり、カットオフ日までにリポジトリに存在しなかった、あるいは1月1日のブロックの一部として参照されていなかったSHA-1ハッシュのオブジェクトは二度と受け付けないようにする。
これなら、リポジトリに新しいSHA-1の衝突を持ち込むことは不可能になるはずだ。
必要なGitの新機能はこれだけ:
a) SHA-256のオブジェクトがSHA-1のオブジェクトを参照できるという実質的な互換性
b) 許可されたSHA-1ハッシュのリスト(あるいはツリー)を保持する新しいオブジェクトタイプ。これはSHA-256でハッシュ化し、コミットからリンクできるようにする仕組み
c) 事前に構成されたSHA-256コミットから到達可能なSHA-1オブジェクトのみを許可するようにリポジトリを設定するポリシーメカニズム
つまりリポジトリを移行すると、「please see commit <sha1>」といったテキストを含むコミットメッセージがすべて壊れるってことだよね。
大惨事になるぞ。データベース内に既存のSHA-1を残せるような互換モードを追加するまでリリースしないでほしいな。
彼らは何年も前から議論して計画を立てて、ようやくデフォルトを切り替えるタイミングを発表したわけだよね。
今さら「彼らがやっていることはすべて間違いだ」と投稿するのが適切なタイミングなのかな?君はその議論のすべてに参加して、どう対処するのがベストか意見したのかい?SHA-256が最善の解決策だったかどうかとか。
代替案についての話や、なぜそれが優れている可能性があるのか、あるいはなぜここでの提案が却下されたのか、どこにも書いていないように見えるよ。
なんだか後出しジャンケンばかりしているようにしか見えない。
理解不能なほど高コストで、最終的には無価値で回避可能な世界的な悪夢になるだろう。
タイトルに「costly(高コスト)」とあり、サブヘッダーに「incomprehensibly expensive(理解不能なほど高コスト)」とあったので、現代のマシンでSHA-256がいかにパフォーマンス不足かという議論かと思ったけど、何も書かれていなかったね。ハードウェアアクセラレーションはないの?どれくらい悪化するんだろう?
この記事は間違いと誤解を招く主張だらけだよ。
SHA-1の脆弱性は理論上のものだと主張しているけど、2017年のSHAtteredはまさに実践的な概念実証だった。Gitが影響を受けなかった唯一の理由は、git-blobのプレフィックスをブルートフォース(総当たり)しようとする人がいなかったからにすぎない。
衝突攻撃は重要ではなく、セカンドプレイメージ攻撃だけが重要だと主張している。これは誤りだ。衝突攻撃はコードのすり替え問題には十分なんだ。2つのリポジトリが同じGitコミット(フルコミットハッシュで検証済み)にあるにもかかわらず、Gitチェックアウトに含まれるコードが異なるという状況が作れるから。
リーナス・トーバルズの「真のセキュリティは配布にある」という引用は、「Gitのコンテンツアドレッシングシステムをコンテンツのアドレス指定に使ってはならない」と言っているわけではない。「curl|sh」のようなケースでは、sha256sumゲートを使って確認済みのコンテンツに固定するのではなく、HTTPSサーバーから取得していることを保証すべきだ、と主張しているんだ。
皮肉かと思ったけど、「Hashmageddon(ハッシュのハルマゲドン)」に対する非常に理にかなった議論だった。
SHA-1の弱点を別のアルゴリズムに変えるだけで解決しようとするなら、SHA-256で衝突が起きたときのために次のアルゴリズムへ移行する覚悟をしておくべきだね。Gitの設計では、そういった暗号的な俊敏性(crypto agility)を持たせるために修正するのは簡単そうに思えない。
署名を使って信頼を確立し、SHA-256を将来何か別のものに入れ替えられるようにしようという彼らの提案はいいと思う。
Fossil SCM(SQLiteの作者が作ったもう一つのバージョン管理システム)の面白い話の一つに、SHAttered攻撃が公開されてから6日後にSHA-1の使用をパッチしたというのがあるよ。
「FossilもGitも最初はSHA-1ハッシュのみを使っていた。しかし、SHA-1に対するSHAttered攻撃が2017年2月23日に公開された際、より強力なハッシュアルゴリズムへの移行が必要だと認識された。Fossilは2017年3月1日(SHAttered公開から6日後)にSHA3-256を代替として使用する機能を追加した。現在、SHA3-256はFossilのすべての新規リポジトリとチェックインでデフォルトになっている。SHAttered以前の古いチェックインは元のSHA-1ハッシュをそのまま使える。そのため、リポジトリを再構築する必要もなければ、ハイパーリンクが壊れることもなかった」
https://fossil-scm.org/home/doc/trunk/www/hundredandone.md
Gitが今でもこの決定で苦労しているのをリアルタイムで見ている身としては、Fossilにとってはたった1週間の開発作業だったというのはすごく興味深い。
あのドキュメント全体を読むのは楽しいよ。別の面白い事実として、Fossilはコミットを保存するのに「grow-only set(拡張のみ可能な集合)」を使っているんだ。これはCRDTによって正式に定義される数年前に彼らが思いついた手法だよ!
2007年のリーナス・トーバルズの発言:
重要なのは、Gitに関していえば、SHA-1はセキュリティ機能ですらないということだ。単なる一貫性チェックにすぎない。セキュリティ部分は別のところにある。だから多くの人は、GitはSHA-1を使っているし、SHA-1は暗号学的に安全なものに使われているから、Gitにも強力なセキュリティ機能があると思い込んでいる。でも実際にはセキュリティとは何の関係もなくて、当時手に入る最高のハッシュだったというだけなんだ... [1]
[1] https://www.youtube.com/watch?v=4XpnKHJAok8&t=56m20s
つまりトーバルズがSHA-1を使ったのは、純粋に「コンテンツを識別する」こと以外の特性を必要としないハッシュ関数が必要だったからなんだよ。
みんな勘違いしてるみたいだけど、問題はサブモジュールの非互換性(Python2からPython3への移行みたいな感じだけど、それよりもっとひどい)だけじゃないんだ。最大の問題は、その場で変更される(多くのリポジトリがそうなるだろうけど)リポジトリのトレーサビリティ(追跡可能性)が失われることだよ。以下のような事態が起きることを想像してみて:
サプライチェーンセキュリティにおいてコミットハッシュを使用しているSLSAやProvenance(来歴)、SBOMデータ。これまでのイメージがすべて存在しないコミットを指すようになる
記事でも指摘されている通り、あらゆるドキュメントとツール類
プロジェクトツールからGitリポジトリへの追跡用リンク。過去のデータはすべてリンク切れになり、失われてしまう
だから、その場でのリプレース(置換)のための移行パスなんて絶対に存在してほしくないね!