ガイドSC

ハッシュ・SHA-2・SHA-3・HMAC・MAC・デジタル署名

公開: 2026-09-26更新: 2026-09-26
署名付きソフトウェア配布を例に、ハッシュ一致、HMAC、署名が証明する範囲と鍵漏えい・旧版再配布への対処を学ぶ。

APP-1へ配布するソフトウェア更新パッケージpkg-41を、外部の配布サイトから取得するとします。SHA-256のハッシュ値が一致すれば安全でしょうか。共有鍵で作るHMACと、配布元の秘密鍵で作るデジタル署名は何を追加で保証するのでしょうか。以下の構成、署名ID、ログは教材用の架空例です。

読む順序は、ハッシュと認証の違い→署名付きパッケージの検証手順→改ざん・鍵漏えい時の判断→運用→演習です。ハッシュ、SHA-2、SHA-3、MAC、HMAC、デジタル署名を別々の入力・鍵・検証者として整理します。

1. まず『何を誰が検証するか』を固定する

用語

このパッケージ配布での役割

暗号学的ハッシュ

任意長の入力から固定長のダイジェストを計算する。pkg-41のバイト列を同じ方式で計算すれば一致を調べられる。公開ハッシュ値だけでは、攻撃者もパッケージと値の両方を置き換えられる。

SHA-2

SHA-256、SHA-384、SHA-512などのハッシュ関数群。この例はSHA-256でpkg-41のダイジェストを計算する。出力が256ビットでも暗号鍵は使わない。

SHA-3

SHA3-256などを含む別の構造のハッシュ関数群。SHA-256とSHA3-256は名前の数字が同じでも別の関数で、出力を混ぜて比較できない。SHA-3だから認証が付くわけではない。

MAC(Message Authentication Code)

共有秘密鍵から作る認証タグ。鍵を持つ者が作ったデータかを共有者同士で確認する。検証者も同じ鍵で偽造できるため、第三者への署名者証明には向かない。

HMAC

ハッシュ関数と秘密鍵を規定の構成で組み合わせたMAC。HMAC-SHA-256なら共有鍵を使いタグを作る。単純に`SHA256(secret || message)`を計算する方式と同一ではない。

デジタル署名

配布元だけが持つ秘密鍵で対象データへ署名し、APP-1は公開鍵で検証する。署名の数学的成功に加え、その公開鍵が信頼する配布元のものかを確認する。内容の秘密は守らない。

この例では配布元がpkg-41とmanifest-41を作り、署名鍵SIGN-7でmanifest-41へ署名します。manifestにはパッケージID、版、対象、SHA-256値、発行時刻を含めます。APP-1は配布元の検証鍵を事前に信頼登録し、受け取った署名、manifest、pkg-41を照合してから適用します。

署名付きパッケージの発行と検証ハッシュ一致と署名検証は別の操作。APP-1は両方を確認する。配布元配布サイトAPP-11. pkgと署名を配置2. pkgとmanifestを取得3. 3点を渡す4. 登録済み鍵を照合
署名付きパッケージの発行と検証

ハッシュ一致と署名検証は別の操作。APP-1は両方を確認する。

図の三点はpkg-41、manifest-41、その署名です。APP-1から配布元への矢印は概念上の鍵照合で、必ずリアルタイム接続する意味ではありません。既に信頼登録した公開鍵や証明書チェーンで検証する設計もあります。配布サイトが攻撃されても署名秘密鍵が守られ、検証が正しければ偽パッケージを拒否できます。

2. SHA-2とSHA-3の読み分け

SHA-256は同じ入力に同じ256ビット値を返し、入力が1ビット違っても通常は異なる値になります。安全な用途では、異なる二つの入力で同じ値を見つけにくい衝突耐性、指定値に一致する入力を見つけにくい原像困難性などが重要です。『絶対に衝突しない』という意味ではありません。

項目

SHA-2とSHA-3で確認すること

アルゴリズム識別

`sha256`と`sha3-256`を別値として保存・比較する。『256ビット』だけで同一方式と扱わない。

入力バイト列

ファイルの改行、圧縮、署名前後、文字コードなどが変わればハッシュも変わる。検証する正確なバイト列を指定する。

用途

ハッシュは完全性の部品。出所確認には信頼された署名やHMACが要る。パスワード保存には高速なSHA-256単体を使わない。

変更時

旧方式から新方式へ移るなら、manifestのアルゴリズム識別と検証実装を併せて更新する。方式を黙って変更すると正常なpkgも不一致になる。

pkg-41のハッシュをWebページに載せ、パッケージも同じ侵害済みサイトから配るだけでは、攻撃者が両方を差し替えられます。比較元の値を信頼できる別経路で受け取るか、配布元の署名でmanifestを保護する必要があります。ハッシュ一致が示すのは、比較した二つのバイト列の関係であり、開発工程が安全だったことではありません。

3. HMACと署名の鍵を誰が持つか

配布元とAPP-1が秘密鍵K-41を共有し、manifestにHMAC-SHA-256を付ける設計もできます。APP-1は同じ鍵でタグを再計算して照合します。ただしAPP-1が侵害されればK-41も漏えいし、攻撃者が有効なタグを作れます。複数受信者が同じ鍵を使うと、一受信者の侵害が他にも波及します。

デジタル署名ではAPP-1に署名秘密鍵を渡しません。APP-1は公開鍵だけを使い、配布元が署名した対象と一致するかを検証します。ただし公開鍵を攻撃者のものへ差し替えれば、偽署名を受け入れます。証明書チェーン、鍵指紋、鍵ID、利用用途、失効状態を、信頼できる配布経路に結び付けます。

ハッシュ・HMAC・署名の検証者同じ完全性確認でも、秘密鍵の有無と第三者への説明力が違う。ハッシュHMAC電子署名秘密鍵不要共有鍵署名者のみ検証者誰でも共有者公開鍵保有者出所確認別経路が必要共有者の範囲鍵の身元確認本文の秘匿なしなしなし
ハッシュ・HMAC・署名の検証者

同じ完全性確認でも、秘密鍵の有無と第三者への説明力が違う。

署名は『署名対象のバイト列を、その秘密鍵を使える主体が署名した』ことの証拠です。組織として誰が承認したか、署名鍵が侵害されていないか、ビルド内容に脆弱性がないかは、署名検証だけでは決まりません。法的な否認防止の扱いも運用・法制度の条件が別に必要です。

4. manifestと検証ログを読む

次は簡略化した架空ログです。実際にはダイジェストは長いので値を省略し、結果だけ示します。署名対象はmanifestの正確なバイト列です。パッケージのハッシュ、manifestの署名、適用してよい版を別々に検証します。

text
12:00:00 pkg=pkg-41 version=3.2 target=APP-1
  manifest_hash_alg=sha256 signer_key=SIGN-7
12:00:01 check=signature result=ok
  trust=ok scope=software-update
12:00:02 check=package_hash result=ok
  expected=manifest-41 observed=pkg-41
12:00:03 check=version_policy result=ok action=install

ログの結果

言えること/言えないこと

signature=ok

登録した公開鍵でmanifestの署名が検証できた。公開鍵の登録が正しく、署名鍵が漏れていないことは別途確認する。

trust=ok

APP-1の信頼設定に合う鍵だった。信頼設定自体が書き換えられていないかは管理ログで調べる。

package_hash=ok

pkg-41のバイト列がmanifestに書かれた値と合う。manifestが署名対象なら配布途中の差替え検知につながる。

version_policy=ok

許可した版・対象に合う。署名された古い脆弱版へのロールバックを防ぐため、最低版と失効・撤回情報も管理する。

正常な署名付きpkg-41を攻撃者が配布サイトからコピーして再配布しても、署名は通ります。署名は配布元が作った内容を検証するもので、配布サイトの正当性や配布の新しさを単独で証明しません。版の制限、更新時刻、署名鍵の失効・撤回情報を組み合わせます。

5. 攻撃・異常・復旧

異常と攻撃条件

判断・対策

pkgだけ差替え

攻撃者が配布サイトを書き換えたが署名鍵を持たない場合。manifestが正規ならハッシュ不一致で拒否する。

pkgと未署名ハッシュを差替え

ハッシュ値も同じ場所で改ざんできれば一致してしまう。信頼できる署名・別経路が必要。

HMAC共有鍵の漏えい

鍵を持つ攻撃者は偽タグを作れる。鍵IDで対象を特定し、共有先を停止・再発行し、受理済みpkgを調査する。

署名秘密鍵の漏えい

攻撃者が正しい署名を生成できる。鍵失効・新鍵配布、信頼設定の更新、侵害期間に署名された成果物の再評価が必要。

正規署名の旧版を再配布

署名とハッシュは成功し得る。最低許可版、単調に増える版、撤回リストなどでロールバックを拒否する。

正規鍵で悪性ビルドを署名

暗号検証は全て通る。ビルド工程、依存物、承認、署名操作の監査、公開後の検証が必要。

ハッシュ方式を変える場合は、発行側と検証側の双方に識別子を追加し、旧方式をいつまで許すか決めます。署名鍵の更新では新鍵を安全な経路で登録し、旧鍵で署名した既存版をどう扱うか定めます。鍵漏えい時は、鍵を交換して終わりではなく、その鍵で受理された成果物と導入先を棚卸しします。

5-1. ハッシュの性質を設問の言葉に置き換える

性質

pkg-41での意味

原像困難性

指定されたハッシュ値から、それに合うpkg本体を作りにくい。ただし短い候補集合のパスワードなら総当たりできる。

第二原像困難性

既存のpkg-41と同じ値になる別のpkgを見つけにくい。配布物の差替えを考えるときに関係する。

衝突耐性

攻撃者が異なる二つのpkgを選んで同じ値にすることが難しい。『出力が有限だから絶対に衝突しない』わけではない。

雪崩効果

小さな入力差で出力が大きく変わる傾向。ただしこれだけで衝突耐性や真正性を証明できない。

一般的なnビットの安全なハッシュでは、原像探索の目安は約2のn乗、衝突探索の目安は誕生日効果により約2のn/2乗です。これは理想化した計算量の説明であり、実装ミスや弱い入力、アルゴリズム固有の攻撃がないことの保証ではありません。SHA-256の出力長と『256ビットの衝突耐性』を同一視しないようにします。

5-2. HMACの入力と再送を守る

APP-1向け管理APIがHMACを使うなら、単に本文だけをタグに入れず、HTTPメソッド、パス、本文のハッシュ、時刻、nonce、鍵IDなどを明確な形式で結び付けます。そうしないと有効なタグ付き本文を別の操作へ転用される可能性があります。正確な入力の順序とエンコードを送受で揃える必要があります。

HMACタグが正しくても、過去の正しい要求をそのまま再送する攻撃は別問題です。時刻の許容幅、使い捨てnonceや要求IDの保存、重複拒否を組み合わせます。時刻だけに頼る場合は許容窓内の再送が残ります。MACの検証成功、リプレイ拒否、業務上の承認をそれぞれログに分けます。

5-3. 署名対象を曖昧にしない

署名がmanifest-41だけに付いているなら、manifestにpkg-41のハッシュが含まれ、そのハッシュを検証して初めてpkg-41へ信頼が届きます。署名対象に版や対象端末が含まれないと、正規署名を別の文脈へ使い回す余地が生まれます。『署名あり』ではなく『何のバイト列を署名したか』を読むことが要点です。

JSON manifestを署名する場合、キー順序、空白、文字コード、数値表現が変わると署名対象のバイト列も変わります。正規化規則を決めるか、配布時の元バイト列をそのまま検証します。パーサが意味的に同じと解釈しても、署名はバイト列に対して検証されます。

確認する識別子

検証で使う理由

signature_alg

RSA-PSSやECDSAなど、実際の署名方式を明示する。攻撃者が自由に弱い方式へ変更できないよう許可リストを設ける。

hash_alg

SHA-256とSHA3-256を取り違えない。対象のpkgとmanifestにどちらを使うか分けて指定する。

signer_key_id

検証鍵を選び、失効・漏えい時に影響した成果物を探す。鍵ID自体の記載だけでは身元の証明にならない。

target / version

APP-1向けのpkg-41版3.2かを確認する。正規署名の別端末向けpkgや旧版を拒否する。

build_id

配布元のビルド記録と結び付ける。署名後の配布物が一致しても、ビルド工程侵害の有無は追加調査が必要。

鍵の漏えいが疑われるときは、署名時刻を自己申告のmanifest値だけで確定しません。署名サービスの監査ログ、ビルドシステム、配布サイトの公開履歴、APP-1の受信時刻を突き合わせます。侵害期間に発行されたpkgを隔離し、信頼できるビルドから再発行したものを検証・再配布します。

検証エラーを一つの『署名失敗』へ丸めてしまうと、運用者は原因を絞れません。内部ログでは、信頼鍵の不一致、署名対象の不一致、pkgのハッシュ不一致、版の拒否を別イベントとして残します。一方、外部へ詳細な鍵情報や内部パスを返す必要はありません。

6. 科目B(午後)の判断と演習

設問では、検証した値が『配布元の署名で守られたmanifest』なのか『同じサイトにある公開ハッシュ』なのかを区別します。また検証者が秘密鍵を持つHMACと、公開鍵だけでよい署名の違いから、鍵漏えい時の影響範囲を説明します。

演習1:公開ハッシュ

条件:pkgとSHA-256値を同じサイトから取得し一致した。質問:配布元の真正性を証明できるか。解答:できない。攻撃者が両方を差し替え得る。誤答『SHA-256一致なら正規』は比較元への信頼を見落としている。

演習2:SHA3-256への変更

条件:発行側だけSHA-256からSHA3-256へ変えた。質問:同じpkgで検証は通るか。解答:通常は通らない。別関数の出力を比較している。誤答『どちらも256ビットだから同じ』はアルゴリズム識別を無視する。

演習3:HMAC鍵の共有

条件:配布元とAPP-1が同じHMAC鍵を持つ。質問:APP-1が第三者へ配布元だけが作ったと証明できるか。解答:できない。APP-1もタグを作れる。誤答『HMACが一致したから署名者確定』は鍵の共有を忘れている。

演習4:署名検証成功

条件:`signature=ok`だが検証鍵は攻撃者が登録した。質問:pkgを受け入れてよいか。解答:いけない。公開鍵の身元と信頼設定を確認する。誤答『数学的に署名成功』は鍵の真正性を無視する。

演習5:旧版の再配布

条件:署名済みの脆弱版3.0が再配布された。質問:署名検証だけで防げるか。解答:防げない。許可最低版や撤回情報で拒否する。誤答『正規署名なら最新』は新しさを署名の保証と混同している。

演習6:秘密鍵漏えい後

条件:SIGN-7の秘密鍵が漏れた。質問:新鍵登録以外に何をするか。解答:旧鍵を失効し、侵害期間の署名済みpkg、適用先、ビルド工程を調査する。誤答『鍵更新だけ』は既に受理した悪性pkgを見逃す。

7. 一次資料

NIST FIPS 180-4:SHA-2を含むSecure Hash Standard

NIST FIPS 202:SHA-3とSHAKE

RFC 2104:HMAC

NIST FIPS 186-5:デジタル署名

この記事についてAIに深掘り質問する

ChatGPT、Claude、Perplexityにこの記事を参照させ、要点の確認や疑問点を自由に質問できます。

次におすすめの学習

編集・検証について

編集・検証:IT資格ラボ編集部

IPAが公開する試験要綱・シラバス・過去問題と、各技術の公式資料を優先して内容を確認しています。制度変更や誤りを確認した場合は、記事を見直して更新します。

編集方針・情報源・訂正方針を見る
この記事を共有する