先に読むと理解しやすい記事:エンコード・暗号化・ハッシュ / 共通鍵暗号・公開鍵暗号
署名は内容と対応する秘密鍵の使用を確かめる
電子署名は、データに対応する検証用の値を秘密鍵で作り、公開鍵で確かめる仕組みです。たとえば配布する設定ファイルへ運営者が署名し、受信したアプリが信頼する公開鍵で検証してから読み込みます。
検証に成功すると、適切な方式と鍵管理の下で、内容が改ざんされていないことと、対応する秘密鍵で署名されたことを確認できます。その公開鍵が運営者のものだという対応付けは、別に信頼できる方法で確保する必要があります。
参照:出典 s1
作成と検証で使う鍵を分ける
送信者は文書のバイト列に秘密鍵で署名します。受信者は同じバイト列、署名、送信者の公開鍵を検証機能へ渡します。署名を見た目で比較したり、署名の文字列があるだけで受理したりしません。
次は処理の関係を示す擬似コードです。検証に失敗した場合は設定を適用しません。署名方式の内部でハッシュを使う場合も、利用側が独自に組み合わせず、ライブラリーの仕様に従います。
説明用の通信例・設定例・擬似コード
signature = sign(privateKey, configBytes)
if not verify(trustedPublicKey, signature, configBytes):
rejectConfig()
else:
applyConfig(configBytes)MACは送信者と検証者が同じ秘密を持つ
MACはMessage Authentication Codeの略で、共有する秘密鍵を使って内容の改ざんなどを検証する値です。HMACはハッシュ関数を用いるMACの構成で、HMAC-SHA-256などがあります。受信者は同じ鍵とデータから検証します。
電子署名では公開鍵を持つ検証者は署名を作れません。一方MACでは、検証者も共有鍵を持つので、新しい正しいMACを作れます。特定の一人だけが作ったと第三者へ示したい用途と、信頼するシステム同士で確認する用途を区別します。
正しい署名でも古い通知の再送は別に防ぐ
仮定の例として、入金通知の本文とMACだけを検証するAPIを考えます。攻撃者が以前の正しい通知を再送すると、MACは依然として正しいため、同じ入金を二重計上するおそれがあります。
通知の一意なIDや時刻も検証する対象へ含め、受信側で処理済みIDや許容時間を確認します。署名やMACは内容の真正性を確認する部品であり、一度しか実行しない業務処理の設計まで代行しません。
検証するのは受け取った同じバイト列
JSONの空白や改行、キーの並びが違うと、意味が似ていてもバイト列は変わります。Webhookなどでは、サービスが定める方法で本文を検証し、必要なら解析前の元の本文を使います。独自に整形してから検証すると、正規の通知まで失敗する場合があります。
署名を付けても本文は暗号化されません。秘密にしたいなら通信や保存の暗号化を別途使います。また、署名が正しい文書でも記載内容が事実か、実行して安全かは別の判断です。
公開鍵の配布元と鍵の漏えいを確認する
確認問題:攻撃者が文書と公開鍵を両方差し替えられるなら、署名が正しいだけで運営者の文書と判断できるでしょうか。答えはできません。攻撃者自身の鍵で署名できるため、信頼する公開鍵を別の確実な方法で入手します。
秘密鍵が漏れたら、攻撃者も正しい署名を作れます。旧鍵の拒否、新しい鍵の配布、影響範囲の調査が必要です。RFC 2104はHMACの構成を確認する資料として参照し、古い文書に出るMD5などを現在の推奨として採用するものではありません。
出典・確認範囲
- [s1] SubtleCrypto: sign() methodMDN / 確認日 2026-11-03
- [s2] HMAC: Keyed-Hashing for Message AuthenticationIETF / RFC 2104 / 確認日 2026-11-03
- [s3] SubtleCrypto: verify() methodMDN / 確認日 2026-11-03
通信例・設定例・被害の例は、仕組みを理解するための仮定です。特定の製品で発生した事件を示すものではありません。ブラウザやサービス固有の設定は、利用する環境の公式資料でも確認してください。