【初心者】AES-256-GCM をイメージで解説 ― 暗号化と「改ざんの検知」を一度に行う仕組み

前提の記事

この記事は、暗号化に使う共通の鍵を Diffie-Hellman 鍵交換で共有できることを前提にしています。鍵交換の仕組みは 【初心者】Diffie-Hellman 鍵交換をイメージで解説 を参照してください。

VPN の設定や TLS の暗号スイートで、aes-256-gcm という名前をよく見かけます。Palo Alto で AES-GCM を選ぶと「認証は none」にしますが、暗号化だけでなく認証もできると言われても、何をどう認証しているのかイメージしにくいところです。

この記事では、数式を使わずに、AES が何をしているのか、GCM がどうやって暗号化と「改ざんの検知(認証)」を一度に行うのかを、身近なものにたとえて説明します。

この記事でわかること
  1. AES は「鍵で決まる手順でデータをかき混ぜる」共通鍵暗号であること
  2. 暗号化だけでは、中身を読まれなくても書き換えられてしまうこと
  3. GCM は「目隠しシート」で暗号化し、「封印(タグ)」で改ざんを見つけること
  4. IPsec や TLS の設定で、AES-256-GCM がどこに出てくるのか

名前を分解する

まず、AES-256-GCM という名前を3つに分けてみます。

部分意味
AES暗号のアルゴリズムの名前(Advanced Encryption Standard)。送る側と受け取る側が同じ鍵を使う「共通鍵暗号」
256鍵の長さが 256 ビット。AES の鍵の長さは 128/192/256 ビットの3種類がある
GCMAES の使い方(モード)の名前(Galois/Counter Mode)。暗号化と改ざんの検知を一度に行う

つまり AES-256-GCM は、「256 ビットの鍵を使う AES を、GCM という使い方で使う」という意味です。以下、AES と GCM を順に見ていきます。

AES は「鍵で決まるかき混ぜ方」

共通鍵暗号のイメージ

AES は共通鍵暗号です。送る側は鍵を使ってデータを読めない形(暗号文)にし、受け取る側は同じ鍵で元に戻します(復号)。同じ鍵を両側で持っておく必要がありますが、その鍵は Diffie-Hellman 鍵交換で安全に共有できます。

アリスボブ暗号文(中身は読めない)共通の鍵で暗号化同じ鍵で復号鍵そのものは Diffie-Hellman 鍵交換で安全に共有しておく
図1 共通鍵暗号のイメージ

AES がしていること

AES は、データを 16 バイト(128 ビット)ずつに区切り、その 16 バイトを、鍵で決まる手順で何度もかき混ぜます。トランプ 16 枚を、鍵ごとに決まったやり方で並べ替えたり、別のカードに置き換えたりする作業を何回も繰り返すイメージです。鍵が 256 ビットの AES-256 では、このかき混ぜを 14 回繰り返します(AES-128 では 10 回)。

この手順は鍵で決まっているので、同じ鍵を持っていれば逆の手順をたどって元の並びに戻せます。鍵を持っていない人には、どう戻せばよいかがわかりません。

元のデータ(16 バイト)ABCDEFGHIJKLMNOPAES鍵で決まる手順でかき混ぜる×14回暗号化されたデータ3FA90C7ED251B86AE4179BC02DF64885同じ鍵があれば、逆の手順で元に戻せる(復号)
図2 AES は 16 バイトのデータを鍵で決まる手順でかき混ぜる
ブロックとモード

AES そのものは「16 バイトを 1 つかき混ぜる」ことしかできません。実際のデータは何百バイトもあるので、AES を何回、どう使って長いデータを暗号化するかを決める必要があります。この使い方を「モード」と呼び、GCM はその一つです。ほかに CBC(AES-CBC)などのモードがあります。

GCM は「目隠しシート」と「封印」

目隠しシートで暗号化する(カウンターモード)

GCM では、データそのものを AES でかき混ぜるのではなく、「番号札」をかき混ぜます。1、2、3 と毎回違う番号札を AES に入れると、鍵を知らない人にはランダムにしか見えない模様ができます。これを「目隠しシート」と呼ぶことにします。

このシートをデータに重ねると、中身が読めなくなります。受け取った側は、同じ鍵と同じ番号札から同じシートを作り、もう一度重ねることで元のデータに戻します。この部分を「カウンターモード(CTR)」と呼びます。

番号札 1AES目隠しシート+データ 1暗号文 1番号札 2AES目隠しシート+データ 2暗号文 2番号札 3AES目隠しシート+データ 3暗号文 3シートは毎回違う模様。同じシートをもう一度重ねると、元のデータに戻る
図3 番号札から目隠しシートを作ってデータに重ねる
番号札は使い回さない

同じ鍵で同じ番号札を二度使うと、同じ目隠しシートが二度使われることになります。そうなると、2つの暗号文を見比べて中身の手がかりを得られたり、後で説明する封印を偽造できたりしてしまいます。そのため GCM では、同じ鍵で同じ番号札(ナンス)を二度使ってはいけないと決められています。IPsec や TLS では、機器がこの番号を自動で管理し、使い切る前に鍵を作り直します。

暗号化だけでは足りない理由

目隠しシートで中身は隠せました。ところが、暗号化しただけでは困ることがあります。目隠しシートは、データの決まった位置に決まった模様を重ねるだけなので、暗号文のある位置を書き換えると、復号したデータの同じ位置が変わります。

たとえば「振込額」が何バイト目にあるかを知っている攻撃者は、中身を読めなくても、その位置の暗号文だけを書き換えられます。受け取った側は、何も気付かずに書き換わった金額を復号してしまいます。

元のデータ振込額 10,000 円暗号文xx 8f a3 2c …攻撃者中身は読めない金額の位置の模様だけを書き換える書き換え後の暗号文受け取って復号振込額 90,000 円暗号化だけでは書き換えに気付けない
図4 暗号化だけでは、中身を読まれなくても書き換えられる

そこで必要になるのが、「途中で書き換えられていないか」を確かめる仕組みです。これを「メッセージ認証」や「完全性のチェック」と呼びます。

封印(認証タグ)で改ざんを見つける

GCM は、暗号化と同時に「封印」も作ります。封印は、暗号文全体から鍵を使って計算する 16 バイトの値で、「認証タグ」と呼ばれます。手紙の封筒に押す封蝋のようなもので、中身が 1 ビットでも変わると、まったく違う封印になります。

受け取った側は、届いた暗号文から同じ鍵で封印を作り直し、届いた封印と比べます。一致すれば、途中で書き換えられていないこと、そして同じ鍵を持つ相手が作ったことがわかるので、復号して使います。一致しなければ、そのデータは捨てます。鍵を持たない攻撃者は、書き換えた暗号文に合う正しい封印を作れません。

送る側宛名(AAD)暗号化しない暗号文封印を作る(GHASH)封印(タグ)16 バイト受け取る側届いた宛名+暗号文から同じ鍵で封印を作り直す届いた封印と比べる一致 → 復号して使う不一致 → 捨てる
図5 封印(認証タグ)を作って付け、受け取った側で確かめる

封印の対象には、暗号化しないデータも含められます。たとえば、パケットの宛名にあたるヘッダは、途中の機器が読めるように暗号化はしませんが、書き換えられては困ります。こうした「暗号化はしないが、封印で守るデータ」を AAD(Additional Authenticated Data、追加認証データ)と呼びます。

このように、暗号化(目隠しシート)と認証(封印)を1つの手順で行う方式を、AEAD(Authenticated Encryption with Associated Data、認証付き暗号)と呼びます。AES-GCM は代表的な AEAD です。

2種類の「認証」

ネットワークの設定では「認証」という言葉が2つの意味で使われます。GCM の認証は、届いたデータが書き換えられていないかを確かめる「データの認証」です。一方、IKE の事前共有鍵や TLS の証明書で行うのは、通信相手が本物かを確かめる「相手の認証」です。Diffie-Hellman だけでは防げないなりすましを防ぐのは、後者の「相手の認証」です。

これまでの方式との違い

GCM が広まる前は、AES-CBC などで暗号化し、別に HMAC-SHA などで改ざん検知用の値を付ける、という2段階の方法がよく使われていました。金庫(暗号化)と封印(改ざん検知)を、別々の道具で用意するイメージです。

項目AES-CBC + HMAC-SHAAES-GCM
暗号化AES-CBCAES(カウンターモード)
改ざんの検知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 バイトが基本です。

IP ヘッダESP ヘッダSPI・シーケンス番号IV8 バイト暗号化されたデータ元の IP パケットなどICV(タグ)16 バイト封印(タグ)で守られる範囲(ESP ヘッダは AAD)暗号化される範囲
図6 AES-GCM を使う ESP パケットの中身

IV は、番号札(ナンス)を作るための値で、パケットごとに変わります。IV は封印の計算に使う番号札の一部なので、IV を書き換えても封印が合わなくなります。

Palo Alto と Azure VPN Gateway のサイト間 VPN の記事では、AES-256-GCM を次のように設定し、確認しました。

場所設定・表示意味
Palo Alto の IPSec 暗号プロファイル暗号化 aes-256-gcm、認証 noneGCM が改ざん検知も行うので、別の認証は使わない
Palo Alto の IKE 暗号プロファイル暗号化 aes-256-gcm、認証 non-auth同じ理由で、IKE でも別の認証は選ばない
Azure の IPsec ポリシーIPsec 暗号化 GCMAES256、IPsec 整合性 GCMAES256暗号化と整合性(改ざん検知)の両方を GCM で行う
Palo Alto の表示AES256-GCM16/COMBINED16 バイトの認証タグを使う AES-256-GCM。暗号化と改ざん検知を一緒に行っている

TLS 1.3

TLS 1.3 の暗号スイートは、すべて AEAD です。たとえば TLS_AES_256_GCM_SHA384 は、データの暗号化と改ざん検知を AES-256-GCM で行います。後ろの SHA384 はデータの改ざん検知用ではなく、Diffie-Hellman で作った鍵の元から暗号化用の鍵を作るときなどに使うハッシュです。

まとめ

項目ポイント
AES16 バイトずつ、鍵で決まる手順でかき混ぜる共通鍵暗号。AES-256 は 256 ビットの鍵で 14 回かき混ぜる
暗号化だけの弱点中身は読めなくても、位置を狙って書き換えられてしまう
GCM の暗号化番号札を AES でかき混ぜて目隠しシートを作り、データに重ねる(カウンターモード)。番号札は使い回さない
GCM の認証暗号文と AAD から鍵を使って封印(16 バイトの認証タグ)を作り、受け取った側で作り直して比べる
AEAD暗号化と改ざん検知を1つの手順で行う方式。だから設定で別の認証アルゴリズムを選ばない
2種類の認証GCM はデータの認証。相手の認証は IKE の事前共有鍵や TLS の証明書で行う

コメント