この記事は、暗号化に使う共通の鍵を Diffie-Hellman 鍵交換で共有できることを前提にしています。鍵交換の仕組みは 【初心者】Diffie-Hellman 鍵交換をイメージで解説 を参照してください。
VPN の設定や TLS の暗号スイートで、aes-256-gcm という名前をよく見かけます。Palo Alto で AES-GCM を選ぶと「認証は none」にしますが、暗号化だけでなく認証もできると言われても、何をどう認証しているのかイメージしにくいところです。
この記事では、数式を使わずに、AES が何をしているのか、GCM がどうやって暗号化と「改ざんの検知(認証)」を一度に行うのかを、身近なものにたとえて説明します。
- AES は「鍵で決まる手順でデータをかき混ぜる」共通鍵暗号であること
- 暗号化だけでは、中身を読まれなくても書き換えられてしまうこと
- GCM は「目隠しシート」で暗号化し、「封印(タグ)」で改ざんを見つけること
- IPsec や TLS の設定で、AES-256-GCM がどこに出てくるのか
名前を分解する
まず、AES-256-GCM という名前を3つに分けてみます。
| 部分 | 意味 |
|---|---|
| AES | 暗号のアルゴリズムの名前(Advanced Encryption Standard)。送る側と受け取る側が同じ鍵を使う「共通鍵暗号」 |
| 256 | 鍵の長さが 256 ビット。AES の鍵の長さは 128/192/256 ビットの3種類がある |
| GCM | AES の使い方(モード)の名前(Galois/Counter Mode)。暗号化と改ざんの検知を一度に行う |
つまり AES-256-GCM は、「256 ビットの鍵を使う AES を、GCM という使い方で使う」という意味です。以下、AES と GCM を順に見ていきます。
AES は「鍵で決まるかき混ぜ方」
共通鍵暗号のイメージ
AES は共通鍵暗号です。送る側は鍵を使ってデータを読めない形(暗号文)にし、受け取る側は同じ鍵で元に戻します(復号)。同じ鍵を両側で持っておく必要がありますが、その鍵は Diffie-Hellman 鍵交換で安全に共有できます。
AES がしていること
AES は、データを 16 バイト(128 ビット)ずつに区切り、その 16 バイトを、鍵で決まる手順で何度もかき混ぜます。トランプ 16 枚を、鍵ごとに決まったやり方で並べ替えたり、別のカードに置き換えたりする作業を何回も繰り返すイメージです。鍵が 256 ビットの AES-256 では、このかき混ぜを 14 回繰り返します(AES-128 では 10 回)。
この手順は鍵で決まっているので、同じ鍵を持っていれば逆の手順をたどって元の並びに戻せます。鍵を持っていない人には、どう戻せばよいかがわかりません。
AES そのものは「16 バイトを 1 つかき混ぜる」ことしかできません。実際のデータは何百バイトもあるので、AES を何回、どう使って長いデータを暗号化するかを決める必要があります。この使い方を「モード」と呼び、GCM はその一つです。ほかに CBC(AES-CBC)などのモードがあります。
GCM は「目隠しシート」と「封印」
目隠しシートで暗号化する(カウンターモード)
GCM では、データそのものを AES でかき混ぜるのではなく、「番号札」をかき混ぜます。1、2、3 と毎回違う番号札を AES に入れると、鍵を知らない人にはランダムにしか見えない模様ができます。これを「目隠しシート」と呼ぶことにします。
このシートをデータに重ねると、中身が読めなくなります。受け取った側は、同じ鍵と同じ番号札から同じシートを作り、もう一度重ねることで元のデータに戻します。この部分を「カウンターモード(CTR)」と呼びます。
同じ鍵で同じ番号札を二度使うと、同じ目隠しシートが二度使われることになります。そうなると、2つの暗号文を見比べて中身の手がかりを得られたり、後で説明する封印を偽造できたりしてしまいます。そのため GCM では、同じ鍵で同じ番号札(ナンス)を二度使ってはいけないと決められています。IPsec や TLS では、機器がこの番号を自動で管理し、使い切る前に鍵を作り直します。
暗号化だけでは足りない理由
目隠しシートで中身は隠せました。ところが、暗号化しただけでは困ることがあります。目隠しシートは、データの決まった位置に決まった模様を重ねるだけなので、暗号文のある位置を書き換えると、復号したデータの同じ位置が変わります。
たとえば「振込額」が何バイト目にあるかを知っている攻撃者は、中身を読めなくても、その位置の暗号文だけを書き換えられます。受け取った側は、何も気付かずに書き換わった金額を復号してしまいます。
そこで必要になるのが、「途中で書き換えられていないか」を確かめる仕組みです。これを「メッセージ認証」や「完全性のチェック」と呼びます。
封印(認証タグ)で改ざんを見つける
GCM は、暗号化と同時に「封印」も作ります。封印は、暗号文全体から鍵を使って計算する 16 バイトの値で、「認証タグ」と呼ばれます。手紙の封筒に押す封蝋のようなもので、中身が 1 ビットでも変わると、まったく違う封印になります。
受け取った側は、届いた暗号文から同じ鍵で封印を作り直し、届いた封印と比べます。一致すれば、途中で書き換えられていないこと、そして同じ鍵を持つ相手が作ったことがわかるので、復号して使います。一致しなければ、そのデータは捨てます。鍵を持たない攻撃者は、書き換えた暗号文に合う正しい封印を作れません。
封印の対象には、暗号化しないデータも含められます。たとえば、パケットの宛名にあたるヘッダは、途中の機器が読めるように暗号化はしませんが、書き換えられては困ります。こうした「暗号化はしないが、封印で守るデータ」を AAD(Additional Authenticated Data、追加認証データ)と呼びます。
このように、暗号化(目隠しシート)と認証(封印)を1つの手順で行う方式を、AEAD(Authenticated Encryption with Associated Data、認証付き暗号)と呼びます。AES-GCM は代表的な AEAD です。
ネットワークの設定では「認証」という言葉が2つの意味で使われます。GCM の認証は、届いたデータが書き換えられていないかを確かめる「データの認証」です。一方、IKE の事前共有鍵や TLS の証明書で行うのは、通信相手が本物かを確かめる「相手の認証」です。Diffie-Hellman だけでは防げないなりすましを防ぐのは、後者の「相手の認証」です。
これまでの方式との違い
GCM が広まる前は、AES-CBC などで暗号化し、別に HMAC-SHA などで改ざん検知用の値を付ける、という2段階の方法がよく使われていました。金庫(暗号化)と封印(改ざん検知)を、別々の道具で用意するイメージです。
| 項目 | AES-CBC + HMAC-SHA | AES-GCM |
|---|---|---|
| 暗号化 | AES-CBC | AES(カウンターモード) |
| 改ざんの検知 | HMAC-SHA を別に計算 | 同じ手順の中で認証タグを作る |
| 設定で選ぶもの | 暗号化と認証(ハッシュ)の両方 | 暗号化だけ(認証は none や non-auth にする) |
| 処理 | CBC の暗号化は前のブロックの結果を使うので、順番に処理する | 番号札ごとにシートを作れるので、まとめて処理しやすい |
AES-GCM は暗号化と改ざん検知が一体になっているため、設定で別の認証アルゴリズムを選ぶ必要がありません。これが、Palo Alto で AES-GCM を選ぶと「認証は none(IPsec)/non-auth(IKE)」にする理由です。
IPsec と TLS で見る AES-256-GCM
IPsec(ESP)
IPsec の ESP で AES-GCM を使うと、パケットは次のようになります。暗号化されるのはデータ部分で、ESP ヘッダ(SPI とシーケンス番号)は暗号化されませんが、AAD として封印で守られます。最後に付く ICV(Integrity Check Value)が封印(認証タグ)で、16 バイトが基本です。
IV は、番号札(ナンス)を作るための値で、パケットごとに変わります。IV は封印の計算に使う番号札の一部なので、IV を書き換えても封印が合わなくなります。
Palo Alto と Azure VPN Gateway のサイト間 VPN の記事では、AES-256-GCM を次のように設定し、確認しました。
| 場所 | 設定・表示 | 意味 |
|---|---|---|
| Palo Alto の IPSec 暗号プロファイル | 暗号化 aes-256-gcm、認証 none | GCM が改ざん検知も行うので、別の認証は使わない |
| Palo Alto の IKE 暗号プロファイル | 暗号化 aes-256-gcm、認証 non-auth | 同じ理由で、IKE でも別の認証は選ばない |
| Azure の IPsec ポリシー | IPsec 暗号化 GCMAES256、IPsec 整合性 GCMAES256 | 暗号化と整合性(改ざん検知)の両方を GCM で行う |
| Palo Alto の表示 | AES256-GCM16/COMBINED | 16 バイトの認証タグを使う AES-256-GCM。暗号化と改ざん検知を一緒に行っている |
TLS 1.3
TLS 1.3 の暗号スイートは、すべて AEAD です。たとえば TLS_AES_256_GCM_SHA384 は、データの暗号化と改ざん検知を AES-256-GCM で行います。後ろの SHA384 はデータの改ざん検知用ではなく、Diffie-Hellman で作った鍵の元から暗号化用の鍵を作るときなどに使うハッシュです。
まとめ
| 項目 | ポイント |
|---|---|
| AES | 16 バイトずつ、鍵で決まる手順でかき混ぜる共通鍵暗号。AES-256 は 256 ビットの鍵で 14 回かき混ぜる |
| 暗号化だけの弱点 | 中身は読めなくても、位置を狙って書き換えられてしまう |
| GCM の暗号化 | 番号札を AES でかき混ぜて目隠しシートを作り、データに重ねる(カウンターモード)。番号札は使い回さない |
| GCM の認証 | 暗号文と AAD から鍵を使って封印(16 バイトの認証タグ)を作り、受け取った側で作り直して比べる |
| AEAD | 暗号化と改ざん検知を1つの手順で行う方式。だから設定で別の認証アルゴリズムを選ばない |
| 2種類の認証 | GCM はデータの認証。相手の認証は IKE の事前共有鍵や TLS の証明書で行う |
コメント