この記事でわかること
- ハッシュ、MAC、デジタル署名の違い
- 「どこまで届くか」で見ると、3つの方式がすっきり分かること
- デジタル署名だけでは認証が成立しない理由と、PKIの役割
3行まとめ
- ハッシュは、改ざん検知だけ
- MACは、改ざん検知と認証まで
- デジタル署名は、改ざん検知と認証と否認防止まで
やりたいことは、まずこの3つ
- 改ざん検知:送ったものが、途中で書き換えられていないこと
- 認証:送った人が、本当にその人であること
- 否認防止:後から「送っていない」と言わせないこと
| 方式 | 改ざん検知 | 認証 | 否認防止 |
|---|---|---|---|
| ハッシュ | ○ | × | × |
| MAC | ○ | ○ | × |
| デジタル署名 | ○ | ○ | ○ |
ハッシュ:改ざん検知だけ
できること
- 対象データを固定長の文字列に変換する
- 同じデータからは、同じハッシュ値が生成される
- 相手からもらったハッシュ値と、こちらで計算したハッシュ値が同じなら、改ざんされていないと判断できる
できないこと
- 誰が作ったかの証明
- 後から「作っていない」と言わせないこと
なぜ届かないのか
ハッシュ値とデータを渡す人が攻撃者であることは、否定できません。
攻撃者がデータとハッシュの両方を作り直せば、受け取る側は気づけません。
実務例
- ダウンロードファイルのチェックサム
- ファイルとチェックサムの両方を、信頼できない場所から取ってきたら、そのチェックサム自体が信用できない
MAC:改ざん検知と認証まで
できること
- 改ざん検知
- 認証
共通の秘密鍵を使うことで、ハッシュの変換方式を二人だけのものにします。
二人だけでしか使われない変換であることがわかるため、「共通鍵を知っている相手が作った」と判断できます。
できないこと
- 否認防止
二人とも変換が可能だからです。
どちらが作ったかは、証明できていません。
実務例
- WebhookのHMAC検証
- サービス側と受け取る側で秘密鍵を共有し、通知が本当にそのサービスから来たものかを確認する
- 相手が特定の1社で、後から第三者に証明する必要がない場面では、MACで十分
MACでは足りない場面
- 後から第三者に「この人が送った」と証明したい場面
デジタル署名:3つ全部
できること
- 改ざん検知
- 認証
- 否認防止
仕組み
- 秘密鍵で署名する
- 公開鍵で検証する
検証方法は二人で共有できますが、変換方法は共有されていません。
署名を作れるのは、秘密鍵の持ち主だけです。
否認防止が成り立つ条件
秘密鍵が適切に管理されている前提で、秘密鍵の持ち主だけが作れる以上、後から「作っていない」と言っても、署名がそれを否定する根拠になります。
実務例
- JWTのRS256
- TLSのサーバ証明書
- コード署名
検証する側はたくさんいても、作る側は1人(または1組織)でなければならない場面で使います。
署名だけでは、認証は成立しない
ここが、勉強していて一番引っかかったところです。
署名の検証でわかること
- 「この署名は、この公開鍵に対応する秘密鍵で作られた」ということ
署名の検証だけではわからないこと
- 「この公開鍵の持ち主が誰なのか」ということ
攻撃者は、自分の秘密鍵と公開鍵のペアを作って、「これがAさんの公開鍵です」と言い、自分の秘密鍵で署名すれば、検証は通ってしまいます。
結論
認証局を使うのは、デジタル署名に何かを追加する、という話ではありません。
デジタル署名が成り立つための前提として、公開鍵と持ち主の対応を保証する仕組みが、そもそも必要だということです。
PKIの流れ
手順
-
発行前の確認
- 認証局は、申請者が本当にそのドメインを管理しているかを確認します
- DNSに指定された文字列を置かせたり、サーバに指定されたファイルを置かせたりする方法です
-
証明書の発行
- 認証局は「このドメインの公開鍵はこれです」という証明書を発行します
- 実際には、ルート認証局が直接サイトの証明書に署名するのではなく、ルート認証局が署名した中間認証局が、サイトの証明書に署名するのが一般的です
-
チェーンの検証
- 検証する側は、サイトの証明書から中間認証局の証明書、さらにルート認証局の証明書へと、チェーンを辿って署名を検証します
- ここで使うルート認証局の公開鍵は、サイトから受け取るのではなく、ブラウザやOSが最初から持っている信頼できるものです
-
署名以外の確認
- 証明書のドメイン名が、アクセスしようとしているURLと一致すること
- すべての証明書が有効期限内であること
- 失効していないこと
これらが揃って、初めて中の公開鍵を信頼できます。
この保証が崩れる場合
- 認証局の秘密鍵が漏れた場合
- 認証局が確認を怠って誤発行した場合
- ブラウザの信頼する認証局の一覧が改ざんされた場合
補足:認証局だけが唯一の方法ではない
公開鍵の対応を保証する方法は、認証局だけではありません。
- 直接会って公開鍵を渡す
- 事前に安全な方法で配布する
ただ、不特定多数のサイトと初めて会う相手の公開鍵を保証するには、認証局のような第三者が必要になるため、WebではPKIが標準になっています。
署名で崩れやすいポイント
-
署名は、秘密にすることではない
- 暗号化されていないJWTでは、署名されたデータそのものは読めます
- 秘密にしたいなら、別に暗号化が必要です
- JWTのペイロードに個人情報やパスワードを入れてはいけない、というのはこの理由です
-
秘密鍵が漏れたら、否認防止は崩れる
- 作れる人が1人でなくなるからです
-
署名の検証だけでは不十分
- JWTであれば、有効期限、発行者、宛先も確認しないと、古いトークンや別サービス用のトークンが通ってしまいます
まとめ
- ハッシュ:改ざん検知だけ。誰でも同じ値を作れる。
- MAC:改ざん検知と認証まで。共通鍵を共有する二人だけが作れるが、二人とも作れるため否認防止はできない。
- デジタル署名:改ざん検知、認証、否認防止まで。作れるのは秘密鍵の持ち主だけで、検証は公開鍵で誰でもできる。
- デジタル署名の認証が成り立つには、前提として公開鍵の本物性を保証する仕組みが必要で、WebではそれがPKIである。
仕組み順で覚えようとすると混乱しやすいですが、目的から「どこまで届くか」で見ると、3つの方式の違いがすっきりします。