🎓 レベル:標準 | 重要度:A(必須) 📎 前提:公開鍵暗号
要点(BLUF)
- デジタル署名は公開鍵暗号を逆向きに使う。秘密鍵で署名し、公開鍵で検証することで「本人が作った/改ざんされていない」を保証する。
- 守るのは真正性(なりすまし防止)と完全性(改ざん検知)。機密性は守らない(中身は隠れない)。
- 「その公開鍵は本当に本人のものか」を保証するのが証明書と PKI。認証局(CA)を起点にした信頼の連鎖で裏づける。
概念:署名は「公開鍵暗号の逆使い」
公開鍵暗号(公開鍵暗号)は「公開鍵で施錠→秘密鍵で解錠」でした。デジタル署名はこれを逆に使います。
- 署名(作成):本人だけが持つ秘密鍵でメッセージの指紋に署名する。
- 検証:誰でも持てる公開鍵で、その署名が正しいかを確かめる。
秘密鍵を持つのは本人だけなので、検証が通れば「確かに本人が作り、かつ改ざんされていない」と分かります。これは手書きサインや封蝋の電子版です。
仕組み:ハッシュ+秘密鍵
実際の署名はメッセージ全体ではなく、その**ハッシュ(指紋)**に対して行います(対称鍵暗号とハッシュ)。
- 送信者:メッセージを SHA-256 などでハッシュ化し、その指紋を秘密鍵で署名する。
- 受信者:同じメッセージを自分でハッシュ化し、送られた署名を公開鍵で検証。一致すれば真正かつ無改ざん。
メッセージを書き換えると指紋が変わり、署名検証が失敗します。だから改ざんは必ず露見します。代表方式は RSA 署名、ECDSA、Ed25519(高速・安全で現代の既定の一つ)です。
仕組み:証明書と PKI(信頼の連鎖)
署名検証には「正しい公開鍵」が要ります。しかし偽の公開鍵をつかまされたら、なりすましを本物と誤認します。これを防ぐのが 証明書 と PKI(公開鍵基盤) です。
証明書は「この公開鍵は確かに ◯◯ のものだ」と、信頼された第三者=認証局(CA)が署名した電子文書です。検証側は CA の署名を確かめることで、相手の公開鍵を信頼できます。CA 自身もより上位の CA に署名され、最終的に OS やブラウザに最初から入っているルート CAにたどり着きます。これが**信頼の連鎖(chain of trust)**です。
flowchart TD
ROOT["ルートCA(端末に内蔵・信頼の起点)"] -->|"署名"| INT["中間CA"]
INT -->|"署名"| LEAF["サーバ証明書(example.com の公開鍵)"]
LEAF -->|"検証側が連鎖をたどる"| TRUST["相手の公開鍵を信頼してよいと判断"]
REVOKE["失効リスト(CRL・OCSP)"] -. "失効していないか確認" .-> LEAF
防御側の使い方/設定
- 署名は真正性・完全性の確認に使う:ソフトウェア配布物、トークン(セッションとトークン(JWT))、文書の出所確認など。
- 証明書チェーンを必ず検証する:相手の証明書がルートまで連鎖し、有効期限内で、失効していない(OCSP/CRL)ことを確認する。
- ホスト名の一致を確認する:証明書のドメインと接続先が一致するか。ここを省くと中間者攻撃に弱い。
- アルゴリズムを固定する:受け側で許可する署名アルゴリズムを明示し、弱い方式を拒否する。
なぜ安全か:秘密鍵の独占+第三者の保証
署名が真正性を保証するのは、署名を作れるのは秘密鍵の持ち主だけだからです。さらに PKI は「その公開鍵が誰のものか」を信頼された CA の署名で裏づけ、偽の公開鍵によるなりすましを防ぎます。アルゴリズムは公開(オープン設計=セキュリティ設計原則)で、安全性は秘密鍵の秘匿だけに依存します。
security-study/labs/digital_signature_demo.py(Ed25519)の実行結果(抜粋):
=== 1. 正しい公開鍵 + 正しいメッセージ -> 検証成功 ===
検証成功(発信元と完全性を確認)
=== 2. メッセージを改ざん -> 検証失敗 ===
改ざん検知 OK -> InvalidSignature
=== 3. 別人の公開鍵で検証 -> 失敗 ===
なりすまし拒否 OK -> InvalidSignature
正しい組み合わせだけが検証を通り、改ざんやなりすましは InvalidSignature で確実に拒否されます。
仕組みの直観
デジタル署名は**封蝋(シーリングワックス)**です。自分の印章(秘密鍵)でしか押せない紋章を手紙に押し、受け取った人は公開された紋章の見本(公開鍵)と照合します。証明書はその印章が本物だと役所(CA)が保証した証明書付き。役所もさらに上位の役所に保証され、最後は国(ルート CA)に行き着きます。
⚠️ よくある誤解・設定ミス
- 「署名すれば中身も秘密になる」と思う:署名は真正性・完全性のみ。機密性は暗号化が別途必要。
- 証明書の検証を省く/エラーを無視する:自己署名や期限切れを「とりあえず許可」にすると中間者に弱い。
- ホスト名検証を外す:証明書は有効でも宛先違いなら危険。一致確認は必須。
- 失効を確認しない:盗まれた鍵の証明書が失効しても、確認しなければ使われ続ける。
- 秘密鍵を共有する:署名鍵を複数人で使うと「誰が署名したか」が崩れる。
対応 lab
security-study/labs/digital_signature_demo.py— Ed25519 署名の作成・検証、改ざん/なりすましの拒否
関連
- 署名の土台 → 公開鍵暗号・対称鍵暗号とハッシュ
- 証明書を使う通信 → TLSと安全な通信
- 署名つきトークン → セッションとトークン(JWT)