ファイルのチェックサムを効率的に生成して検証するにはどうすればよいですか?

ファイルのチェックサムを効率的に生成して検証するにはどうすればよいですか?

通常は複雑なディレクトリ階層内にネストされている大規模なファイル コレクションのチェックサムをキャプチャして検証できるようにしたいと考えています。

すべてのファイルにチェックサムが必要ですか? 既存のディレクトリ構造を活用して、たとえばファイル ツリー内のノードのみを検証し、その中のすべてのファイルを検証する必要は必ずしもないような方法はありますか?

答え1

チェックサムを使用する最も効率的な方法は、コンピューターにすべてを実行させることです。ZFS などのファイルシステムを使用すると、データが書き込まれるときにすべてのデータのチェックサム (実際にはチェックサムよりも強力なハッシュを使用) を計算し、データが読み取られるたびにそれを検証します。もちろん、ZFS には、ファイルの削除または上書きがいつ間違いで、いつが通常の操作であるかがわからないという欠点がありますが、ZFS はすべてに対してコピーオンライト セマンティクスを使用するため、スナップショット機能を使用してリスクを軽減できます。

ZFS は、RAID5 スタイルのパリティ、ドライブ ミラー、複製コピーなど、設定した冗長性を使用して、ハッシュ チェックに失敗したデータを自動的に復元することもできます (ZFS ファイルシステムに copies=N プロパティを追加すると、書き込んだデータの N 個のコピーが保存されます)。また、ハッシュは Merkle ツリーに保存されます。Merkle ツリーでは、ファイルのハッシュ値はブロックのハッシュに依存し、ディレクトリ エントリのハッシュはそこに含まれるファイルとディレクトリのハッシュ値に依存し、ファイルシステムのハッシュはルート ディレクトリのハッシュなどに依存します。

最終的にどのような解決策を採用するにせよ、プロセスは CPU の速度ではなく、ディスクの速度によって制限されることが必ずわかります。

また、ディスクの BER も忘れずに考慮してください。結局のところ、ディスクは回転する錆びた板にすぎません。消費者レベルのドライブのエラー率は、10^14 ビットの読み取りごとに 1 ビットの誤読み取りです。つまり、11 テラバイトの読み取りごとに 1 ビットということになります。11 テラバイトのデータ セットがあり、その中のすべてのファイルのハッシュを計算すると、チェックサムの 1 つが誤って計算され、データ セット内のファイルの 1 つのブロックが永久に破損することになります。ただし、ZFS は、プール内のすべてのディスクに書き込んだすべてのブロックのハッシュを知っているため、どのブロックが失われたかがわかります。その後、プール内の冗長性 (パリティ、ミラー、または追加のコピー) を使用して、そのブロックのデータを正しい値で書き換えることができます。これらの安全機能は、zfs send または receives を使用してプライマリ システムからバックアップにデータをコピーする場合にも適用されます。

しかし、ベンはコメントで良い点を指摘しています。ZFS は計算したハッシュ値をユーザーに公開しないので、ZFS システムに入力または出力されるデータにはハッシュが付随するはずです。インターネット アーカイブがアーカイブ内のすべてのアイテムに xml ファイルを付けてこれを実行する方法は気に入っています。https://ia801605.us.archive.org/13/items/fakebook_the-firehouse-jazz-band-fake-book/fakebook_the-firehouse-jazz-band-fake-book_files.xml例として。

答え2

おそらく今が話題にするのに良いタイミングだろうバッグイットこれは、デジタル オブジェクトのアーカイブ、長期保存、転送を目的とした、非常にシンプルでありながら強力なファイル パッケージ形式です。ユーザーには、米国議会図書館やカリフォルニア デジタル ライブラリなどがあります。

BagIt ツール (いくつかのプログラミング言語に存在します) は、ファイルを特定のディレクトリ構造に配置し、チェックサムとハッシュを実行します。それだけです。

PS: もちろん、BagIt ツールは、含まれているチェックサム/ハッシュに対してバッグを確認することもでき、バッグにメタデータを追加することもできます。しかし、バッグはこれ以上複雑になることはありません。

答え3

各ファイルのチェックサムを生成します。チェックサムは非常に小さいため、ディレクトリ全体のチェックサムを生成するには、すべてのファイルも処理する必要があります (少なくとも、ディレクトリ エントリのみから作成されるディレクトリ チェックサムについて話していない場合は、データが削除されないように、それらも作成します)。

アーカイブ全体に対して 1 つのチェックサムがあると仮定します。データが破損していることはわかっていますが、これが 1 つのファイルだけなのか、さらに重要なことに、どのファイルなのかはわかりません。個別のチェックサムがあると、柔軟性が高まります。破損した 1 つのファイルを検出し、他のバックアップのファイル (他のファイルが破損している可能性があります) から置き換えることができます。

そうすれば、データが保存される可能性が高くなります。

答え4

回答を読んでみましたが、データ層のエラーを処理するために ZFS を利用するという考えは気に入りましたが、誤って、または悪意を持ってファイルが変更されるという問題が依然として残ります。その場合、ZFS は保護してくれませんし、他の誰かが言ったように、外部検証のためにどこか別の場所に保存する、ユーザーが表示できる「ハッシュ」を提供してくれません。

TripWire という Linux アプリケーションがあり、システム実行ファイルの監視に広く使用されており、攻撃後に変更されていないことを検証します。このプロジェクトは現在は廃止されているようですが、AIDE (Advanced Intrusion Detection Environment)ServerFault で推奨されている という新しいプロジェクトがあります。

https://serverfault.com/questions/62539/tripwire-and-alternatives

インストールすると、ユーザーが設定可能な x 分ごとに実行され、指定したすべてのフォルダーでファイルの変更がないかチェックします。すべてのファイル ハッシュを計算するには 1 回実行する必要があります。その後、すべてのハッシュを現在のファイルと照合し、同じであることを確認します。使用するハッシュの種類またはハッシュの組み合わせ (SHA-256 より弱いものはお勧めしません)、使用するファイル属性 (コンテンツ、サイズ、変更されたタイムスタンプなど)、チェックの頻度、ハッシュ データベースの保存方法と場所などを指定できます。

これをやり過ぎだと考える人もいるかもしれませんが、投稿者の要件によっては、保存しているデータが一定期間後に同じままであるという安心感が得られるかもしれません。

関連情報