GitにおけるSHA-1
Gitがコミット、ツリー、blobの識別にSHA-1をどう使用するかを解説。コンテンツアドレッサブルストレージ、セキュリティの影響、SHA-256への移行について学びます。
詳細な説明
Gitはコンテンツアドレッサブルストレージシステムの基盤としてSHA-1を使用しています。Gitリポジトリ内のすべてのオブジェクト(コミット、ツリー、blob、タグ)はその内容のSHA-1ハッシュで識別されます。この設計がGitの整合性保証を提供し、中央サーバーなしの分散コラボレーションを可能にします。
Gitのオブジェクトハッシュ計算:
Gitはハッシュ前に各オブジェクトにヘッダーを付加します:"<type> <size>\0<content>"。例えば、「hello」を含むblobは"blob 5\0hello"としてハッシュされます。結果のSHA-1ハッシュ(40文字の16進数)がオブジェクトの識別子になります。同じファイル内容は常に同じblobハッシュを生成し、リポジトリ全体と異なるリポジトリ間での重複排除を可能にします。
コンテンツアドレッサブルストレージ:
Gitはオブジェクトを.git/objects/に保存し、最初の2文字の16進数をディレクトリ名、残り38文字をファイル名として使用します。任意のオブジェクトをハッシュで取得できます。コミットはツリーオブジェクトをハッシュで参照し、ツリーはblobをハッシュで参照し、各コミットは親コミットをハッシュで参照します。これにより不変の有向非巡回グラフ(DAG)が作成され、任意のオブジェクトの変更にはすべての子孫ハッシュの変更が必要です。
セキュリティの影響:
SHA-1の既知の衝突攻撃は理論的に、同じGit blobハッシュを持つ2つの異なるファイルを作成可能にします。SHAtteredの研究者は2017年に2つのPDFファイルでこれを実証しました。Gitは既知の衝突パターンを拒否するSHAttered検出メカニズムを実装しましたが、2020年に実証されたより一般的な選択プレフィックス衝突はこの方法では検出できません。ほとんどの開発ワークフローではリスクは低いです。
SHA-256への移行:
Gitは2018年からSHA-256サポートを開発しています。extensions.objectFormat設定でSHA-1の代わりにSHA-256を使用するリポジトリを作成できます。SHA-256リポジトリは機能しますが、エコシステム(GitHub、GitLabなど)はまだ追いついています。移行計画にはSHA-1とSHA-256のオブジェクト名が共存できる互換モードが含まれます。
ユースケース
Gitはリポジトリ内のすべてのコミット、ファイル、ディレクトリを一意に識別するためにSHA-1に依存しており、分散バージョン管理と整合性保証の基盤を形成しています。