HTTPS通信、スマートフォンのストレージ、Wi-Fiパスワード、暗号化ZIPファイル——現代の暗号化シーンの中心にあるのはすべて同じアルゴリズムです:AES(Advanced Encryption Standard)。2001年にNISTが標準化したこの対称暗号は、今日においても破られていない実用的な暗号化の基盤です。AESの仕組みと正しい使い方は、開発者とセキュリティエンジニアに欠かせない知識です。
1. AESの成り立ち
1997年、NISTはDES(Data Encryption Standard)の後継を選ぶ公開コンペを開始しました。DESの56ビット鍵は1999年に22時間で解読されており、時代遅れになっていました。5年間にわたる世界中の暗号学者による公開審査を経て、2001年にNISTはベルギーの暗号学者Joan DaemenとVincent Rijmenが設計したRijndaelアルゴリズムを選定し、AES(FIPS PUB 197)として発布しました。
AESは対称暗号:暗号化と復号に同じ鍵を使います。RSAは非対称暗号:公開鍵で暗号化し、秘密鍵で復号します。HTTPSはその組み合わせです——RSA/ECDHでAESセッション鍵を安全に交換し、実際のデータ転送はAESで行います。
2. 鍵長
AESは3種類の鍵長をサポートしています:
| 鍵長 | ラウンド数 | セキュリティレベル | 主な用途 |
|---|---|---|---|
| AES-128 | 10 | 128ビット | 一般アプリ、TLS |
| AES-192 | 12 | 192ビット | ほとんど使われない |
| AES-256 | 14 | 256ビット | 政府機密、高セキュリティ要件 |
AES-128はほぼすべてのアプリケーションで十分です——総当たり攻撃には2¹²⁸通りの試行が必要で、現在の計算能力では事実上不可能です。AES-256は量子コンピュータに対する防衛(Groverアルゴリズムにより有効鍵長が半減するため、256ビット→128ビットで依然安全)や規制要件(米国政府のTOP SECRET)に使われます。
3. AESの動作原理
AESは128ビット(16バイト)のブロック単位でデータを処理します。鍵長によってラウンド数が決まり、各ラウンドで4つの変換が4×4バイトの状態行列に適用されます:
- SubBytes(バイト置換):各バイトを固定のS-Boxで置換し、非線形性を提供
- ShiftRows(行シフト):各行を異なるバイト数だけ循環左シフトし、列をまたいでデータを拡散
- MixColumns(列混合):各列にGF(2⁸)の乗算を適用し、バイト間の依存性を生成(最終ラウンドは省略)
- AddRoundKey(ラウンド鍵の加算):状態とマスター鍵から派生したラウンド鍵をXOR
4. 暗号化モード:最も重要な選択
AES自体は128ビットのブロックを1つ暗号化する方法を定義するだけです。任意長のデータには「暗号化モード」が必要です。この選択は鍵長よりも重要です。
4.1 ECB(電子符号表モード)— 絶対に使ってはいけない
ECBは各ブロックを独立して暗号化します。致命的な欠陥:同じ平文ブロックは同じ暗号文ブロックを生成するため、元データのパターンが保持されます。
ECBでペンギンの画像を暗号化しても、同じ色のピクセル領域が同じ暗号文を生成するため、暗号化後もペンギンの輪郭が見えます。ECBは機密性が必要な場面では絶対に使ってはいけません。
4.2 CBC(暗号文ブロック連鎖モード)— レガシー標準
CBCは各平文ブロックを暗号化前に直前の暗号文ブロックとXORし、最初のブロックにはランダム生成のIV(初期化ベクトル)を使います。パディングが必要で、完全性検証は提供しません。Padding Oracle攻撃に脆弱です。
4.3 GCM(ガロア/カウンターモード)— 現代の標準
GCM = CTR暗号化 + GHASH認証。Authentication Tag(認証タグ)を自動生成し、改ざんを検出します。
- AEAD(認証付き暗号化):機密性と完全性を1回の操作で保証
- パディング不要、完全な並列処理可能
- TLS 1.3でAES-256-GCMが主要暗号スイートとして使用
| モード | パディング | 完全性検証 | 並列処理 | 推奨度 |
|---|---|---|---|---|
| ECB | 必要 | なし | 可 | ❌ 絶対に使わない |
| CBC | 必要 | なし | 復号のみ | ⚠️ レガシー互換のみ |
| CTR | 不要 | なし | 可 | ✅ MAC併用で使用可 |
| GCM | 不要 | ✅ 内蔵 | 可 | ✅✅ 現代の第一選択 |
5. IVとNonce:絶対に使い回さない
- 暗号化のたびに異なるIV/Nonceを使う必要があります——使い回しはセキュリティを著しく損ないます
- IV/Nonceは秘密にする必要はなく、暗号文と一緒に平文で送信できます
- GCMのNonce使い回しは壊滅的:攻撃者が認証鍵を復元し、暗号化スキーム全体を破れます
6. コード例
# PHP(OpenSSL、AES-256-GCM)
$key = random_bytes(32);
$nonce = random_bytes(12);
$ciphertext = openssl_encrypt(
$plaintext, 'aes-256-gcm', $key,
OPENSSL_RAW_DATA, $nonce, $tag
);
# Python(cryptographyライブラリ、AES-256-GCM)
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os
key = os.urandom(32)
nonce = os.urandom(12)
aesgcm = AESGCM(key)
ciphertext = aesgcm.encrypt(nonce, plaintext, None)
# Node.js(組み込みcrypto、AES-256-GCM)
const crypto = require('crypto')
const key = crypto.randomBytes(32)
const nonce = crypto.randomBytes(12)
const cipher = crypto.createCipheriv('aes-256-gcm', key, nonce)
const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()])
const tag = cipher.getAuthTag()
7. まとめ
AESは現代暗号学の基盤です:20年以上の公開審査を経ても破られていません。しかしアルゴリズム自体はほんの一部——正しい使い方こそが実際のセキュリティを提供します。GCMモードを使い(ECBや裸のCBCは避ける)、毎回ランダムなNonceを生成し、KDFで鍵を派生させる(パスワードをそのまま使わない)。この3つを守れば、AESはあなたのアプリケーションに工業グレードの暗号化保護を提供します。