概要
AES(Advanced Encryption Standard)とは、現代で最も広く使われている暗号化規格です。 データを第三者に読み取られないように変換する「共通鍵暗号方式」で、同じ鍵を使って暗号化・復号化します。
例えば、鍵を使ってメッセージを暗号化し、同じ鍵で復号化する仕組みです。米国政府が2001年に標準として採用し、高いセキュリティと高速な処理が特徴です。
AESは私たちの身近なところで使われています。 Wi-FiのWPA2/WPA3、HTTPS通信、APIの暗号化など、 インターネットのセキュリティを支える重要な技術です。
共通鍵暗号方式とは?
AESは共通鍵暗号方式(対称鍵暗号方式)で、暗号化と復号化に同じ鍵を使うのが特徴です。
例えるなら、同じ合鍵を持っている二人だけが開けられる金庫のようなイメージです。 送信者Aさんと受信者Bさんが同じ鍵を持っていて、Aさんが鍵でメッセージを暗号化し、 Bさんが同じ鍵で復号化します。
共通鍵暗号方式のメリット・デメリット
| 項目 | メリット | デメリット |
|---|---|---|
| 処理速度 | ⚡ 非常に高速(公開鍵暗号より100〜1000倍速い) | - |
| 鍵の長さ | 短い鍵で高いセキュリティ(128〜256ビット) | - |
| 鍵の配送 | - | ⚠️ 事前に安全に鍵を共有する必要がある |
| 鍵の管理 | - | ⚠️ 通信相手ごとに異なる鍵が必要(n人なら n(n-1)/2 個の鍵) |
このデメリットを補うため、実際のHTTPS通信ではRSA(公開鍵暗号)とAESを組み合わせて使います。 RSAで共通鍵を安全に交換し、その後の通信はAESで高速に暗号化します。 この組み合わせにより、鍵配送問題を解決しながら高速な暗号化通信を実現しています。
💡 実際の通信例:あなたが今このページを見ているときも、AESが使われています。 ブラウザのアドレスバーに鍵マークが表示されていれば、AESで暗号化された安全な通信(HTTPS)が行われている証拠です。
AESの暗号化の仕組み
AESはブロック暗号と呼ばれる方式で、データを128ビット(16バイト)の ブロックに分割して暗号化します。
AESの処理ステップ
AESは複数の「ラウンド」と呼ばれる処理を繰り返します。 ラウンド数は鍵の長さによって異なります:
- AES-128:10ラウンド
- AES-192:12ラウンド
- AES-256:14ラウンド
各ラウンドでは、以下の4つの処理を実行します:
- SubBytes(バイト置換):各バイトを別の値に置き換える(S-Boxと呼ばれる置換表を使用)
- ShiftRows(行シフト):各行を左にシフトする
- MixColumns(列混合):各列を混合する(最終ラウンド以外)
- AddRoundKey(ラウンド鍵の加算):ラウンド鍵とXOR演算
これらの処理を繰り返すことで、元のデータが全く異なる暗号文に変換されます。同じ処理を逆順で実行することで、暗号文を元のデータに復号化できます。
体験してみよう:AES暗号化
💡 ポイント: 同じ鍵を使わないと復号化できません。これが「共通鍵暗号方式」の基本です。
AES暗号化を体験してみよう
ポイント: 同じ鍵を使わないと復号化できません。
AES-128 vs AES-192 vs AES-256:詳細比較
AESには鍵の長さによって3つのバリエーションがあります。 **鍵が長いほどセキュリティは高まりますが、処理時間も若干長くなります**。
| 項目 | AES-128 | AES-192 | AES-256 |
|---|---|---|---|
| 鍵の長さ | 128ビット(16バイト) | 192ビット(24バイト) | 256ビット(32バイト) |
| ラウンド数 | 10ラウンド | 12ラウンド | 14ラウンド |
| セキュリティ強度 | 2128 通りの鍵 | 2192 通りの鍵 | 2256 通りの鍵 |
| 解読にかかる時間 (総当たり攻撃) | 約1027年 (1兆年の1兆倍) | 約1045年 | 約1063年 (宇宙の年齢の1050倍) |
| 処理速度 | ⚡ 最速 | 中間 | 若干遅い(約20-40%遅い) |
| 推奨用途 | 一般的なWeb通信、 ファイル暗号化 | 政府機関、 高度なセキュリティ要件 | 軍事、機密情報、 長期保存データ |
| 実際の使用例 | Wi-Fi(WPA2)、 HTTPS、VPN | 米国政府の機密情報 (SECRET レベル) | 米国政府の最高機密 (TOP SECRET) |
どれを選ぶべき?
- 一般的な用途(個人、企業):AES-128で十分
→ Wi-Fi、HTTPS、ファイル暗号化など - 高度なセキュリティが必要:AES-256を選択
→ 金融機関、医療データ、個人情報、長期保存データ - AES-192:ほとんど使われない(128と256の中間という中途半端な位置)
💡 重要:AES-128でも事実上解読不可能です。 セキュリティ上の弱点は鍵の長さではなく、鍵の管理ミスや実装の脆弱性であることがほとんどです。
AESの暗号化モード
AESは128ビットのブロックを暗号化しますが、実際のデータはそれより長いことがほとんどです。 複数のブロックをどう処理するかを定める「暗号化モード」が重要です。
主な暗号化モード
1. ECB(Electronic Codebook)モード ❌ 非推奨
各ブロックを独立して暗号化する最もシンプルなモード。
- ⚠️ 同じ平文ブロックは同じ暗号文になる → パターンが見えてしまう
- ⚠️ セキュリティ上の問題があるため、使用すべきではない
2. CBC(Cipher Block Chaining)モード ✅ よく使われる
前のブロックの暗号文を次のブロックの暗号化に使うモード。
- ✅ 同じ平文でも異なる暗号文になる
- ✅ セキュアで広く使われている(SSL/TLS、ファイル暗号化など)
- ⚠️ 初期化ベクトル(IV)が必要
- ⚠️ 並列処理ができない(順次処理のみ)
3. GCM(Galois/Counter Mode)⭐ 最新・最高
暗号化と認証を同時に行う最新のモード。
- ✅ 暗号化 + 改ざん検知を同時に実現
- ✅ 並列処理が可能で高速
- ✅ TLS 1.3(最新のHTTPS)で標準採用
- ✅ 現在最も推奨されるモード
4. CTR(Counter)モード
カウンタ値を暗号化して平文とXORするモード。
- ✅ 並列処理が可能
- ✅ ランダムアクセスが可能(特定のブロックだけ復号化できる)
- ⚠️ 認証機能がない(GCMの方が優れている)
| モード | セキュリティ | 並列処理 | 認証 | 推奨度 |
|---|---|---|---|---|
| ECB | ❌ 弱い | ✅ 可能 | ❌ なし | ❌ 使用禁止 |
| CBC | ✅ 強い | ❌ 不可 | ❌ なし | ✅ 推奨 |
| GCM | ✅ 強い | ✅ 可能 | ✅ あり | ⭐ 最推奨 |
| CTR | ✅ 強い | ✅ 可能 | ❌ なし | ✅ 推奨 |
💡 結論:新規開発ではAES-GCMを使いましょう。 既存システムでCBCを使っている場合も、可能な限りGCMへの移行を検討してください。
AESの実用例
AESは私たちの身近なところで、毎日のように使われています:
- Wi-Fi通信:WPA2/WPA3規格でAESを使用。自宅や職場のWi-Fiで通信が保護されています
- HTTPS通信:Webサイトとの通信を暗号化。URLが「https://」で始まるサイトで使われています
- ファイル暗号化:MacのFileVault、WindowsのBitLockerなど、ディスク全体を暗号化
- VPN通信:リモートワークでの安全な通信に必須
- メッセージングアプリ:WhatsApp、Signal、LINEなどのエンドツーエンド暗号化
- オンラインバンキング:取引情報の保護に使用
- パスワードマネージャー:1Password、LastPassなどでパスワードを安全に保存
JavaScriptでAESを実装する方法
実際にWeb開発でAESを使う場合は、crypto-jsライブラリを使うのが一般的です。npmで簡単にインストールできます。
サンプルコードを見る (JavaScript + crypto-js)
// インストール: npm install crypto-js
const CryptoJS = require('crypto-js');
// === 暗号化 ===
function encrypt(plaintext, password) {
// AES-256-CBCで暗号化(パスワードから鍵を生成)
const ciphertext = CryptoJS.AES.encrypt(plaintext, password).toString();
return ciphertext;
}
// === 復号化 ===
function decrypt(ciphertext, password) {
const bytes = CryptoJS.AES.decrypt(ciphertext, password);
const plaintext = bytes.toString(CryptoJS.enc.Utf8);
return plaintext;
}
// === 使用例 ===
const message = "これは秘密のメッセージです";
const password = "MySecurePassword123";
// 暗号化
const encrypted = encrypt(message, password);
console.log("暗号文:", encrypted);
// 出力例: U2FsdGVkX1+abc123def456...
// 復号化
const decrypted = decrypt(encrypted, password);
console.log("復号文:", decrypted);
// 出力: これは秘密のメッセージです
// ❌ 間違ったパスワードでは復号化できない
const wrong = decrypt(encrypted, "WrongPassword");
console.log("間違ったパスワード:", wrong);
// 出力: (空文字列またはエラー)Web Crypto API(ブラウザ標準)を使う方法
// ブラウザ標準のWeb Crypto APIを使用(ライブラリ不要)
async function generateKey() {
// AES-GCM用の鍵を生成
const key = await crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256 // AES-256
},
true, // 鍵のエクスポートを許可
["encrypt", "decrypt"]
);
return key;
}
async function encryptData(plaintext, key) {
// テキストをバイト配列に変換
const encoder = new TextEncoder();
const data = encoder.encode(plaintext);
// 初期化ベクトル(IV)を生成
const iv = crypto.getRandomValues(new Uint8Array(12));
// 暗号化
const ciphertext = await crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: iv
},
key,
data
);
return { ciphertext, iv };
}
async function decryptData(ciphertext, key, iv) {
// 復号化
const decrypted = await crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: iv
},
key,
ciphertext
);
// バイト配列をテキストに変換
const decoder = new TextDecoder();
return decoder.decode(decrypted);
}
// 使用例
(async () => {
const key = await generateKey();
const message = "秘密のメッセージ";
const { ciphertext, iv } = await encryptData(message, key);
console.log("暗号化完了");
const decrypted = await decryptData(ciphertext, key, iv);
console.log("復号文:", decrypted);
})();AESと他の暗号化方式の比較
AES以外にも様々な暗号化方式があります。それぞれの特徴を理解して、適切なものを選びましょう。
| 暗号方式 | 種類 | 鍵の長さ | 速度 | セキュリティ | 用途 |
|---|---|---|---|---|---|
| AES | 共通鍵 | 128/192/256ビット | ⚡ 非常に速い | ✅ 非常に強い | データ暗号化全般 (現在の標準) |
| DES | 共通鍵 | 56ビット | ⚡ 速い | ❌ 弱い(破られた) | ⚠️ 使用禁止 (歴史的な存在) |
| 3DES | 共通鍵 | 168ビット | 🐢 遅い | ⚠️ 中程度 | ⚠️ レガシーシステム (AESへ移行推奨) |
| RSA | 公開鍵 | 2048/4096ビット | 🐢 非常に遅い | ✅ 強い | 鍵交換、デジタル署名 (AESと併用) |
| ChaCha20 | 共通鍵 | 256ビット | ⚡ 非常に速い | ✅ 非常に強い | モバイル、組み込み (AESの代替) |
AESが選ばれる理由
- 速度とセキュリティのバランス:高速かつ非常に安全
- ハードウェアサポート:現代のCPUにはAES専用命令(AES-NI)が搭載され、さらに高速化
- 国際標準:米国政府が採用し、世界中で標準として使われている
- 実績:20年以上使われており、重大な脆弱性が見つかっていない
AESのセキュリティ:本当に安全?
AESは非常に高いセキュリティを持ち、現時点で現実的な時間内に解読することは不可能とされています。
総当たり攻撃は不可能
例えば、AES-256を総当たり攻撃で破ろうとした場合、 2256 = 約1077通りの鍵を試す必要があります。
仮に1秒間に1兆個(1012)の鍵を試せるスーパーコンピュータを使っても、約1063年かかります。これは宇宙の年齢(約138億年)の1050倍以上です。
実際の脆弱性は「実装」と「運用」
AES自体は安全ですが、以下のような場合に脆弱性が生じます:
- ❌ 弱い鍵:「password」「12345678」など推測しやすい鍵
- ❌ 鍵の漏洩:ソースコードに鍵をハードコード、ログに鍵を出力
- ❌ ECBモードの使用:パターンが見えてしまう危険なモード
- ❌ IVの使い回し:初期化ベクトルは毎回ランダムに生成すべき
- ❌ サイドチャネル攻撃:処理時間や消費電力からの情報漏洩
✅ 安全に使うためのベストプラクティス
- AES-GCMモードを使う(暗号化 + 認証)
- 鍵は環境変数に保存(ソースコードに書かない)
- IV(初期化ベクトル)は毎回ランダム生成
- 実装済みのライブラリを使う(自作しない)
- AES-256を選ぶ(金融・医療など重要データ)
詳しくはMDN Web Crypto APIやNIST AES標準仕様書で確認できます。
AESとゼロデイ攻撃
AESは非常に強固な暗号化方式ですが、ゼロデイ攻撃のような脅威からシステムを守るためには、 暗号化だけでなく多層的なセキュリティ対策が必要です。
AESだけでは防げない攻撃
- マルウェア感染: 暗号化前のデータを盗まれる
- 中間者攻撃: 鍵交換時に盗聴される
- ソーシャルエンジニアリング: ユーザーを騙して鍵を入手
- ゼロデイ脆弱性: 暗号化実装のバグを突かれる
そのため、AES暗号化に加えて、定期的なセキュリティアップデート、 ファイアウォール、侵入検知システム(IDS)などを組み合わせることが重要です。
