SSD Nodes Learn Hosting plans →
ガイド Matt Connor著者 Matt Connor ・更新日 2026-08-26

Linuxでsha256sumを使ってダウンロードを検証する方法

Linuxのsha256sumでファイルをSHA256SUMSと照合する手順を解説します。1バイト変更すると検証が失敗する実例で、チェックサムが証明する範囲も確認できます。

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, August 12, 2026.

チェックサムでダウンロードを2分で検証する

チェックサムでダウンロードを検証するには、受け取ったファイルをハッシュ化し、そのハッシュを公開元が示した値とツールで比較します。sha256sumはこの2つの処理を実行できます。単独ではダイジェストを表示し、-cを指定するとダイジェストの一覧を読み込み、一致するファイルを報告します。このガイドでは、作成したファイルを使って一連の手順を実行します。その後、意図的にファイルを壊し、失敗が発生する様子を確認します。説明を読むだけではありません。

全体を通して、次の点を覚えておいてください。チェックサムで確認できるのは、手元のバイト列がそのダイジェストを生成したバイト列と同じかどうかです。誰がそのバイト列を生成したかは確認できません。後者を確認するには、信頼できる署名と鍵が必要です。このガイドの最後では、この2つの違いを具体的に示します。

練習用のファイルを作成する

システムの他の部分に影響しないよう、作業は一時ディレクトリで行います。以下の各コマンドは GNU coreutils に含まれています。Ubuntu または Debian サーバーに標準で用意されている基本コマンドセットなので、インストールは不要です。

mkdir -p ~/checksum-demo
cd ~/checksum-demo
printf 'the payload of a totally ordinary download\n' > payload.txt
sha256sum payload.txt

1 行が表示されます。64 個の16進数文字、2 個のスペース、ファイル名の順です。この64文字がファイルのダイジェストです。同じコマンドをもう一度実行しても、同じ行が表示されます。ハッシュ値は決定論的であり、同じ入力からは常に同じ出力が得られるためです。ファイルの文字を1つ変更してもう一度実行すると、ダイジェストは少しだけ変わるのではありません。まったく異なる値になります。入力の1ビットを反転すると、出力のおよそ半分のビットが反転するためです。この性質により、64文字の文字列を4 GBのイメージの代用として使用できます。

SHA256SUMS ファイルを保存して確認する

画面に表示したダイジェストは、翌日には役に立ちません。sha256sum 自体が書き出す形式でファイルに保存すると、後でツールから読み戻せます。

sha256sum payload.txt > SHA256SUMS
cat SHA256SUMS
sha256sum -c SHA256SUMS

sha256sum -c はリストの各行を読み取り、その行に記載されたファイルをハッシュ化して、2 つのダイジェストを比較します。正常に実行されると、ファイルごとに 1 行を出力します。

payload.txt: OK

終了ステータスも確認してください。スクリプトはテキストではなく、終了ステータスを読み取るためです。echo $? は、正常に完了すると 0 を出力します。SHA256SUMS という名前は規則ではなく慣例ですが、ディストリビューションやほとんどのリリースページで使われています。そのため、同じ名前を使えば、ファイルを開かなくても内容を次の担当者が把握できます。

1 バイト変更してチェックの失敗を確認する

ここで、意図的にファイルを壊します。次のコマンドはオフセット 5 の 1 バイトだけを書き換え、それ以外は変更しません。そのため、ファイルの長さと名前は維持されます。

printf 'X' | dd of=payload.txt bs=1 seek=5 conv=notrunc status=none
cat payload.txt
sha256sum -c SHA256SUMS

重要なのは conv=notrunc フラグです。このフラグがないと、dd は書き込みが停止した位置でファイルを切り詰めます。その場合、より明らかな種類の破損を検証することになります。チェック結果は次のようになります。

payload.txt: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match

echo $? は 1 を出力します。FAILED は、ファイルが読み取られ、そのダイジェストがリスト内の値と一致しなかったことを示します。元のバイトを戻し、チェック結果が OK に戻ることを確認します。

printf 'the payload of a totally ordinary download\n' > payload.txt
sha256sum -c SHA256SUMS

これが基本的な手順のすべてです。ファイル内のどこであっても 1 バイト異なるだけで、FAILED が生成されます。接続が切れて途中で止まったダウンロード、前日のビルドを提供するミラー、転送中にファイルを書き換えたプロキシ、誤ったブロックを返したディスク。いずれの場合も、同じ行に結果が表示されます。

リストにダウンロードしていないファイルが記載されている場合

実際の SHA256SUMS ファイルには、プロジェクトがリリースするすべてのイメージが記載されており、そのうち 1 つをダウンロードします。ここでは、その状況を再現します。

printf 'a second file\n' > notes.txt
sha256sum payload.txt notes.txt > SHA256SUMS.all
rm notes.txt
sha256sum -c SHA256SUMS.all
payload.txt: OK
sha256sum: notes.txt: No such file or directory
notes.txt: FAILED open or read
sha256sum: WARNING: 1 listed file could not be read

FAILED open or readはFAILEDとは異なる失敗です。この2つを混同すると、切り分けに時間がかかります。FAILEDはバイト列が正しくないことを意味します。FAILED open or readはsha256sumがファイルを取得できなかったため、比較自体が行われていないことを意味します。実際のダウンロードでは、通常、原因は作業ディレクトリです。リスト内のファイル名は、コマンドを実行した場所を基準とする相対パスだからです。ファイルを格納しているディレクトリへ移動し、もう一度実行します。実際に存在するファイルだけを確認するには、次のように指定します。

sha256sum --ignore-missing -c SHA256SUMS.all

payload.txt: OKと出力され、0 で終了します。リストに記載された名前が1つも存在しない場合、--ignore-missingはファイルが0個でも黙って成功しません。no file was verifiedと報告して非0で終了します。これは望ましい動作です。何も確認していないのに成功することが、最も見落としやすい失敗だからです。

目視せずに公開済みのダイジェストを貼り付ける

64 文字の 16 進数を目視で比較する場面で、この習慣は大きな問題になります。先頭 4 文字と末尾 4 文字だけを確認して一致したと判断する人がいますが、それこそ攻撃者が狙う比較方法です。比較はツールに任せます。EXPECTED に公開元からコピーしたダイジェストを設定します。EXPECTED= の後にコピーした値を指定し、-c が想定する 1 行を作成します。

printf '%s  %s\n' "$EXPECTED" payload.txt > payload.sha256
cat payload.sha256
sha256sum -c payload.sha256

ダイジェストとファイル名の間には 2 つの空白があります。そのため、フォーマット文字列にも 2 つの空白が含まれます。これは sha256sum が書き出す形式であり、-c が解析する形式です。ダイジェストだけを含むファイルはチェックサム行ではありません。そのため、チェックでは対象ファイルを推測せず、no properly formatted checksum lines found によりファイル全体を拒否します。プロジェクトによっては、BSD のタグ付き形式を公開しています。これは SHA256 (payload.txt) = の後にダイジェストを続ける形式です。GNU coreutils は sha256sum --tag payload.txt でこの形式を書き出し、-c で読み戻します。どちらの形式で保存しても問題ありません。

チェックの動作がおかしい場合は、cat -A SHA256SUMS でリスト自体を確認します。cat -A SHA256SUMS は各行の末尾を $ で示し、通常は見えない文字も表示します。^M$ で終わる行には、Windows のエディターによる復帰文字が含まれています。GNU sha256sum はこの末尾の文字を無視し、それでも OK を出力します。そのため、CRLF のリストがチェックを壊しているわけではありません。ただし、coreutils 以外のツールはこの形式を許容しない場合があります。保存するコピーは tr -d '\r' < SHA256SUMS > SHA256SUMS.clean で正規化します。

チェックサムで証明できること、できないこと

チェックサムで証明できるのは、ディスク上のバイト列が公開されたダイジェストを生成したバイト列と同一であることです。これにより、偶発的な破損は完全に検出できます。ダウンロードミラー上のファイルを差し替えたものの、ダイジェストを公開したページには手を加えられなかった、という不注意な攻撃者への対策にもなります。

作成者については何も証明しません。ダイジェストが示すのはバイト列に関する事実であり、人に関する事実ではありません。1つのページがファイルとダイジェストの両方を配信している場合、片方を変更できる者はもう片方も変更できます。その場合、OK の行が示すのは、ミラーが自分自身と一致していることだけです。そこで、チェックサムを確認する価値を生む原則は次のとおりです。ファイルを取得した場所とは別の場所からダイジェストを取得します。たとえば、イメージはミラーまたは torrent から取得し、プロジェクト独自のドメインから TLS (transport layer security) 経由でダイジェストを取得します。これで攻撃者は、1か所ではなく2か所を制御する必要があります。また、検証済みのバイト列を実行した後に何をするかについても、チェックサムは何も示しません。これは、インストールスクリプトからエージェントの権限で実行される dsh プラグインまで、自分に代わって実行されるものについて別途確認すべき問題です。

アルゴリズムも重要です。SHA-256 (secure hash algorithm、256-bit 出力) には、2026年8月時点で既知の衝突がありません。そのため、公開者は SHA-256 を使用します。MD5 (message digest 5) と SHA-1 は信頼できません。同じ MD5 ダイジェストを持つ異なるファイルは、2004年以降、作成可能です。また、選択プレフィックス SHA-1 衝突は 2020年に公開されました。MD5SUMS ファイルは、ランダムな破損が意図的に作成された衝突ではないため、途中で切れたダウンロードの検出には使えます。ただし、だれかがあなたを欺こうとしている場合、それを防ぐことはできません。プロジェクトが両方を公開している場合は、SHA-256 の行を使用します。

署名が引き継ぐ範囲

署名は、ダイジェストでは確認できない部分を補います。公開者は秘密鍵でダイジェストファイルに署名し、利用者は公開鍵でそれを検証します: gpg --verify SHA256SUMS.asc SHA256SUMS。検証に成功すれば、そのダイジェスト一覧がその鍵を保有する者から提供されたことを確認できます。続いて sha256sum -c SHA256SUMS により、ディスク上のファイルと一覧の対応が確認され、鍵から実際のバイト列まで検証の連鎖がつながります。

弱点は鍵に移ります。ファイルを提供したのと同じページから鍵を取得すると、攻撃者に両方を置き換える機会を与えてしまいます。GnuPG はこの点を正しく扱っており、最初の検証では Good signature と WARNING: This key is not certified with a trusted signature! が表示されます。Good signature は、暗号学的な計算が成立したことを意味します。利用者が想定しているプロジェクトにその鍵が属していることを意味するわけではありません。別ドメインにあるプロジェクトのドキュメントや、すでにその鍵を収録しているディストリビューションのパッケージなど、別の情報源からフィンガープリントを取得し、末尾 8 文字ではなく完全なフィンガープリントを比較してください。これは SSH の秘密鍵に求められるのと同じ注意 です。理由も同じです。鍵が信頼の判断を担い、その後のすべての検証が鍵を引き継ぐためです。

再現可能ビルドは、この考え方をさらに進めます。公開されたダイジェストだけでは、1 台のマシンがビルドしたバイナリを信頼することになります。プロジェクトのビルドが再現可能であれば、誰でも同じソースをコンパイルしてバイト単位で同一の出力を得られるため、独立したビルダーが公開ダイジェストを検証できます。1 台のサーバーの説明をそのまま信頼する必要はありません。自動化されたパイプラインや機械が作成したパッチを通じてコードが届く機会が増えているため、この点は年々重要になっています。ビルドに受け入れる内容を決めるのはポリシーの問題です。AI 支援コードに関するオープンソースポリシーも、サプライチェーンの反対側から同じ仕組みに取り組みます。

パッケージマネージャーがすでに処理しています

Debian と Ubuntu では、apt が要求しなくてもインストールのたびにこの検証チェーンを実行します。パッケージインデックスには、各 .deb ファイルの SHA-256 ダイジェストが含まれています。Release ファイルにはそれらのインデックスファイルのダイジェストが含まれ、InRelease には Release に対する署名が含まれています。この署名は、/usr/share/keyrings と /etc/apt/trusted.gpg.d の鍵を使って検証されます。チェーンが壊れている場合、apt はそのことを通知します。サードパーティーリポジトリの鍵がない場合は The following signatures couldn't be verified because the public key is not available: NO_PUBKEY、取得したインデックスが署名済みの Release と一致しない場合は Hash Sum mismatch になります。後者は通常、キャッシュプロキシが古いファイルを返したか、ミラーの同期中に取得したことを意味します。

プロジェクトのホームページに、curl からスクリプトを直接 shell にパイプするよう書かれていた場合も、比較対象にすべき基準はこれです。バイト列は何も検証されず、内容を確認することもできません。サーバーは、スクリプトにはある内容を返し、ブラウザーには別の内容を返すこともできます。その場合、後から調査できるコピーも残りません。curl -fsSL <url> -o install.sh でファイルにダウンロードし、ハッシュを計算し、less で内容を読んでから実行してください。この習慣にかかる時間は約 20 秒です。また、他のものをインストールする前に、新しい VPS を最初の 10 分で初期設定する際にも始める価値があります。

手作業でインストールしたもののダイジェスト一覧を保持する

aptでインストールしたパッケージは追跡されます。/usr/local/binにコピーしたバイナリは追跡されず、システム上で監視もされません。ダイジェスト一覧を作成すると、必要なときに確認できます。

printf 'a second file\n' > notes.txt
sha256sum *.txt > inventory.sha256
sha256sum -c --quiet inventory.sha256

すべてのファイルが一致する場合、--quietは何も出力しません。一致しないファイルがある場合は、失敗した行だけを出力します。つまり、無出力が成功を示し、echo $?でその結果を0により確認できます。これはスケジュール実行するジョブに設定する形式です。--statusを使うとさらに厳密になり、何も出力せず、終了ステータスだけを返します。同じパターンを実際のファイルに対してsha256sum /usr/local/bin/* > ~/local-bin.sha256で実行すれば、ベースラインを作成できます。一覧にはパスが入力したとおりに保存されるため、絶対パスを使えば、どのディレクトリからでも確認できます。

そのベースラインにどの程度の価値があるかを明確にしておく必要があります。変更されたファイルは検出できます。しかし、すでに root 権限を取得した攻撃者は検出できません。その攻撃者は、バイナリを書き換えたのと同じようにinventory.sha256も書き換えられるためです。一覧を有効な情報として扱うには、マシンの外部に保管してください。これは、実際にどの程度 VPS を信頼しているのか、またその下層ディスクに誰がアクセスできるのかという、より広い問題の一部です。

FAQ

一致するチェックサムは、ダウンロードが安全であることを意味しますか?

いいえ。比較したダイジェストと、手元のファイルのバイト列が一致していることを意味します。ダイジェストを掲載したページを攻撃者が管理している場合、攻撃者は自分のファイルのダイジェストを掲載するため、検証結果は OK になります。一致が示すのは整合性だけです。安全性を確認するには、別の情報源から取得した鍵で署名を検証する必要があります。その場合に限り、ダイジェストもその信頼性を引き継ぎます。

sha256sum -c が FAILED open or read を出力するのはなぜですか?

ファイルを読み取っていないためです。その直前の行には、検索した名前とともに No such file or directory と表示されています。SHA256SUMS ファイル内の名前は、コマンドを実行するディレクトリからの相対パスです。そのため、ダウンロードを保存したディレクトリに移動して、もう一度実行してください。リストに、ダウンロードしていないファイルも含まれている場合は、--ignore-missing を追加します。open or read のない単純な FAILED は逆の状況を示します。ファイルは読み取られましたが、ダイジェストが一致していません。

ダウンロードの検証に MD5 で十分ですか?

偶発的な破損の確認であれば十分です。転送の途中で切れたファイルや、ディスク上の不良ブロックから、偶然一致する MD5 ダイジェストが生成されることはありません。攻撃者への対策としては不十分です。同じ MD5 ダイジェストを持つ異なるファイルは、2004 年以降、作成可能になっています。SHA-1 も 2020 年に chosen-prefix collision の影響を受けました。プロジェクトが SHA-256 と MD5 の両方を公開している場合は、SHA-256 の行を使用してください。MD5 のみを提供するプロジェクトは、古いリリース手順を使用している兆候と考えてください。

sha256sum -c と gpg --verify の違いは何ですか?

sha256sum -c は、ファイルがダイジェストと一致することを証明します。gpg --verify は、特定の秘密鍵の所有者がダイジェストファイルに署名したことを証明します。確認する内容が異なるため、プロジェクトが両方を提供している場合は、両方を実行してください。署名によってダイジェストのリストが信頼できるものになり、そのリストによってダウンロードしたファイルも信頼できます。

Web ページに表示されたダイジェストで 1 つのファイルを検証するにはどうすればよいですか?

文字列を目視で比較しないでください。ダイジェストとファイル名を 1 行に保存し、その間を 2 つの空白で区切ります。次に、そのファイルに対して sha256sum -c を実行し、出力される OK または FAILED を確認します。printf '%s %s\n' で行を作成すると、sha256sum がファイルを no properly formatted checksum lines found として拒否する原因になる書式ミスを防げます。

#checksums#sha256sum#integrity#supply-chain#security