AES 暗号化モードと共通鍵暗号の徹底解説
暗号化は現代のデジタルセキュリティの基盤です。銀行口座へのアクセス、安全なメッセージの送信、クラウドへの機密データの保存など、暗号化アルゴリズムは舞台裏で情報を保護するために絶えず働いています。その中でも、Advanced Encryption Standard (AES) は、世界で最も広く使用され、信頼されている共通鍵暗号アルゴリズムです。
しかし、AES は単なる一つの「ブラックボックス」ではありません。それをどのように使用するか、特にどの暗号化モードを選択するかは、アルゴリズム自体と同じくらい重要です。この包括的なガイドでは、AES の暗号化モードを深く掘り下げ、比較し、他の共通鍵暗号を探索し、次のプロジェクトのためのセキュリティ推奨事項を提供します。
共通鍵暗号とは?
AES の詳細に入る前に、共通鍵暗号の概念を理解することが重要です。共通鍵アルゴリズムでは、暗号化(平文を暗号文に変換)と復号(暗号文を平文に戻す)の両方に同じ鍵を使用します。
これは、暗号化に公開鍵、復号に秘密鍵を使用する公開鍵暗号(RSA や ECC など)とは異なります。共通鍵暗号は非常に高速で効率的であるため、大量のデータを暗号化するのに適しています。
AES (Advanced Encryption Standard) の理解
AES は、5 年間にわたる公募を経て、2001 年に米国国立標準技術研究所 (NIST) によって制定されました。老朽化した Data Encryption Standard (DES) を置き換えるために設計されました。
AES はブロック暗号であり、データを固定サイズ(128 ビット)のブロックで処理します。128、192、256 ビットの鍵長をサポートしています。アルゴリズム自体は極めて安全ですが、複数のデータブロックを処理する方法、すなわち利用モード (Mode of Operation) に、多くのセキュリティ上の脆弱性が潜む可能性があります。
AES 暗号化モードの詳細解説
1. Electronic Codebook (ECB)
ECB は最も単純な利用モードです。各 128 ビットの平文ブロックが、同じ鍵を使用して独立して暗号化されます。
- 長所: シンプルで高速、並列処理が可能。
- 短所: ほとんどの用途で極めて安全性が低い。同じ平文ブロックが常に同じ暗号文ブロックになるため、データ内のパターンが保持されてしまいます。
- 「ペンギン」問題: ECB の欠陥を示す古典的な例は、ペンギンの画像を暗号化することです。暗号化した後も、暗号文の中にペンギンの輪郭がはっきりと見えてしまいます。
- 結論: 単一のデータブロックを暗号化する場合を除き、ECB は決して使用しないでください。
2. Cipher Block Chaining (CBC)
CBC は、ブロックを「連鎖」させることで ECB を改善します。各平文ブロックは、暗号化される前に前の暗号文ブロックと排他的論理和 (XOR) を取ります。最初のブロックには初期化ベクトル (IV) が使用されます。
- 長所: 平文内のパターンが隠される。長年、業界標準でした。
- 短所: 逐次処理のみ(並列化不可)。適切なメッセージ認証コード (MAC) と併用しない場合、パディングオラクル攻撃に対して脆弱です。
- 結論: 一意で予測不可能な IV と MAC(Encrypt-then-MAC)を正しく使用すれば安全ですが、現在は一般的に GCM に取って代わられています。
3. Counter (CTR)
CTR モードはブロック暗号をストリーム暗号に変えます。連続したカウンタを暗号化することでキーストリームを生成し、そのキーストリームと平文を XOR します。
- 長所: 非常に効率的で、完全な並列化をサポートし、パディングが不要(ストリーム暗号として機能するため)。
- 短所: 同じ(ナンス + カウンタ)が同じ鍵で再利用されると、セキュリティが完全に崩壊します。機密性は提供しますが、完全性は提供しません。
- 結論: 高速アプリケーションには優れていますが、必ず認証メカニズム(HMAC など)と組み合わせる必要があります。
4. Galois/Counter Mode (GCM)
GCM は、認証付き暗号 (AEAD) モードです。暗号化のための CTR モードと、認証のためのガロア体乗算を組み合わせています。
- 長所: 機密性と完全性(認証)の両方を提供します。非常に効率的で並列化をサポートし、多くの一般的な攻撃に耐性があります。また、暗号化されていない「関連データ」を暗号文と一緒に認証することも可能です。
- 短所: ゼロから実装するのは複雑です。CTR と同様に、ナンスの再利用は致命的です。
- 結論: 現代の黄金標準。ほぼすべてのアプリケーション(TLS 1.2+、SSH など)に強く推奨されます。
5. Counter with CBC-MAC (CCM)
CCM は、CTR 暗号化と CBC-MAC 認証を組み合わせた別の AEAD モードです。
- 長所: 暗号化と認証の両方を提供します。WPA2 Wi-Fi セキュリティや Bluetooth Low Energy (BLE) で多用されています。
- 短所: 各データブロックに対して 2 回のブロック暗号処理が必要なため、GCM よりも遅くなります。並列化はできません。
- 結論: GCM が重すぎる可能性があるリソース制約のある環境には適していますが、一般的にはパフォーマンス面で GCM が好まれます。
比較表:AES モード
| モード | タイプ | 並列化可能か? | 認証付きか? | パディング必要か? | 最適なユースケース |
|---|---|---|---|---|---|
| ECB | ブロック | はい | いいえ | はい | 単一ブロックのみ |
| CBC | ブロック | 暗号化:× / 復号:○ | いいえ | はい | レガシーシステム |
| CTR | ストリーム | はい | いいえ | いいえ | 高速ストリーミング |
| GCM | AEAD | はい | はい | いいえ | 現代の Web/API セキュリティ |
| CCM | AEAD | いいえ | はい | いいえ | IoT / Bluetooth / Wi-Fi |
その他の注目すべき共通鍵暗号
AES が主流ですが、他にもいくつかの共通鍵暗号を知っておく価値があります。
- Blowfish: 1993 年に Bruce Schneier によって設計された、高速でパブリックドメインのブロック暗号。安全ですが、現在は後継の Twofish や AES に取って代わられています。
- Camellia: 日本(NTT と三菱電機)で開発されたブロック暗号。セキュリティとパフォーマンスにおいて AES に匹敵し、ISO/IEC 標準です。
- SM4: 中国の無線ネットワーク国家標準。128 ビットのブロックサイズと 128 ビットの鍵を持つブロック暗号です。
- 3DES (Triple DES): DES を 3 回適用するレガシーアルゴリズム。現在は低速と見なされ、AES への移行が進んでいます。
- RC4: かつて SSL/TLS や WEP で広く使用されていたストリーム暗号。現在は脆弱と見なされており、現代のアプリケーションでは使用すべきではありません。
セキュリティ推奨事項:なぜ GCM が好まれるのか
現代のセキュリティにおいて、認証付き暗号 (AEAD) はオプションではなく必須です。多くの開発者は CBC や CTR を使用しながら、メッセージ認証コード (MAC) を追加し忘れるという間違いを犯します。これにより、データはビット反転攻撃やパディングオラクル攻撃に対して脆弱になります。
GCM (Galois/Counter Mode) が好まれる理由:
- 効率性: 非常に高速で、ハードウェア(Intel AES-NI など)による加速が可能です。
- 認証: 暗号文が改ざんされていないかを検出できます。
- パディング不要: パディングを避けることで実装が簡素化され、パディング関連の脆弱性を防げます。
- 標準化: セキュアなインターネット通信の根幹である TLS 1.3 のデフォルトの選択肢です。
コード例
Node.js (組み込みの crypto モジュールを使用)
Node.js で AES-256-GCM を実装する方法は次のとおりです。
const crypto = require('crypto');
function encrypt(text, key) {
const iv = crypto.randomBytes(12); // GCM 標準の IV サイズは 12 バイト
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
const authTag = cipher.getAuthTag().toString('hex');
return {
iv: iv.toString('hex'),
content: encrypted,
tag: authTag
};
}
function decrypt(encryptedObj, key) {
const decipher = crypto.createDecipheriv(
'aes-256-gcm',
key,
Buffer.from(encryptedObj.iv, 'hex')
);
decipher.setAuthTag(Buffer.from(encryptedObj.tag, 'hex'));
let decrypted = decipher.update(encryptedObj.content, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
// 使用例
const key = crypto.randomBytes(32); // 256 ビット鍵
const data = encrypt("Hello Security World!", key);
console.log("暗号文:", data.content);
console.log("復号文:", decrypt(data, key));
FAQ: よくあるエラーと落とし穴
1. 初期化ベクトル (IV) を再利用できますか?
いいえ。 CTR モードや GCM モードで同じ鍵を使用して IV を再利用すると、攻撃者が 2 つの暗号文を XOR して平文を復元できる可能性があります。CBC では、メッセージの開始部分に関する情報が漏洩する可能性があります。常に暗号論的に安全な乱数生成器を使用して、暗号化ごとに一意の IV を作成してください。
2. AES-256 は AES-128 よりもはるかに安全ですか?
どちらも極めて安全です。AES-128 は、今日のブルートフォース攻撃では事実上解読不可能です。AES-256 は、量子コンピュータ(グローバーのアルゴリズムなど)による将来の脅威に対してより高いセキュリティマージンを提供しますが、わずかに低速です。ほとんどの専門家は、大半の商業的ニーズには AES-128 で十分であると同意しています。
3. 同じ入力に対して「暗号化された」テキストが常に同じなのはなぜですか?
ECB モードを使用しているか、固定の IV を使用している可能性があります。これらは両方とも重大なセキュリティリスクです。GCM や CBC などのモードを使用し、操作ごとに新しいランダムな IV を生成していることを確認してください。
4. GCM の認証タグ (Auth Tag) を紛失するとどうなりますか?
復号に失敗します。認証タグはデータが変更されていないことを保証します。これがないとデータの完全性を検証できず、ほとんどのライブラリは final() 呼び出し中にエラーをスローします。
結論
適切な AES モードの選択は、セキュリティ、パフォーマンス、互換性のバランスです。現代の Web アプリケーションにとって、AES-GCM はほぼ常に正しい選択です。機密性、完全性、真正性という暗号化の「三位一体」を提供します。
ECB のようなレガシーなモードを避け、IV 管理に注意を払うことで、ユーザーのデータを覗き見や悪意のある改ざんから確実に保護することができます。