AES(Advanced Encryption Standard)は、2001年に米国国立標準技術研究所(NIST)によって公式標準として採用された対称ブロック暗号アルゴリズムです。AESは旧式のDESに取って代わり、それ以来、銀行システムからモバイルアプリケーションまで、世界で最も普及している暗号アルゴリズムになりました。NIST(2023)によると、AESは256ビット鍵で2^256操作に相当するセキュリティを提供し、最新のブルートフォース攻撃に対して無敵です。 NIST FIPS 197、2023
重要なポイント
AES(Advanced Encryption Standard)は、ベルギーの暗号学者Joan DaemenとVincent RijmenによってRijndaelという名前で開発された対称ブロック暗号です。2001年、NISTは5年間の公開テストと分析の後、Rijndaelを新しい米国暗号標準コンペティションの勝者として選出しました。AESは固定サイズ(128ビット)のデータブロックで動作し、3つの鍵長(128、192、256ビット)をサポートします。変換ラウンド数は鍵長に依存します:128ビットで10ラウンド、192ビットで12ラウンド、256ビットで14ラウンド。各ラウンドには4つの操作が含まれます:SubBytes(S-boxによる非線形バイト置換)、ShiftRows(巡回行シフト)、MixColumns(列混合)、AddRoundKey(ラウンド鍵XOR)。
AESの開発は、1997年にNISTがDESを置き換えるコンペティションを発表したことから始まりました。DESの56ビット鍵は1998年に専用デバイスDeep Crackで22時間で破られました。Serpent(英国)、Twofish(米国)、RC6(米国)など、さまざまな国の15のアルゴリズムが参加しました。1999年の最終ラウンドまでに5つの候補が残りました。Rijndaelは、すべてのプラットフォーム(8ビットマイクロコントローラから64ビットサーバーまで)での高速性、暗号解読への耐性、コンパクトなハードウェア実装の組み合わせにより勝利しました。2006年から、AESは米国政府システムでSECRETおよびTOP SECRET分類データの暗号化に使用されています。現在、AESは主要なプロトコルすべてに組み込まれています:TLS 1.2/1.3、IPsec、SSH、Wi-Fi WPA2/WPA3、Bluetooth BR/EDR。
AESは、128ビット(16バイト)のブロックでデータを処理し、stateと呼ばれる4x4バイト行列として編成されます。各暗号化ラウンドは決定論的変換のシーケンスを実行し、これらが集合的に雪崩効果を生み出します:入力データの1ビットを変更すると、出力ビットの約50%が変化します。この効果により、AESはブロック暗号を破る主要な方法である差分解読法と線形解読法に対して耐性があります。
プロセスはAddRoundKeyから始まります — 初期鍵とstateのXOR。次にラウンドが実行されます:SubBytesは各stateバイトをS-box(置換テーブル)の値で置換します。ShiftRowsは2行目を1位置、3行目を2、4行目を3巡回シフトし、列間の混合を保証します。MixColumnsは各state列をガロア体GF(2^8)の固定行列で乗算し、各出力バイトを列の4つの入力バイトすべてに依存させます。AddRoundKeyはKey Expansionによって元の鍵から導出された次のラウンド鍵でXORします。最終ラウンドではMixColumns操作がありません。復号は逆操作InvSubBytes、InvShiftRows、InvMixColumns、AddRoundKeyを逆順で使用します。モバイル開発者にとって、AESの内部構造を理解する必要はありません — 適切なパラメータでプラットフォームの組み込みAPIを正しく呼び出す方法を知っていれば十分です。
AESの暗号強度を保証する重要な特性は雪崩効果です。平文または鍵の1ビットを変更すると、暗号文ビットの約50%が変化し、AESを差分解読法と線形解読法に対して非常に耐性のあるものにします。SubBytes(S-boxによる非線形性)とMixColumns(ガロア体乗算による拡散)の組み合わせは、暗号文の一部を知っていてもブルートフォースより速く鍵を回復できないような数学的複雑さを生み出します。NIST分析(2018)によると、AES-128に対する最も既知の攻撃 — biclique攻撃 — は実効鍵長をわずか2ビット削減するだけ(126.2ビット)で、攻撃者に実用的な利点を与えません。AES-256に対しては、ブルートフォースを超える実用的に実行可能な攻撃は存在しません。
AESは3つの鍵サイズをサポートし、それぞれが特定の暗号強度レベルに対応します。鍵サイズの選択は、セキュリティ、パフォーマンス、デバイスリソース要件に影響します。
| 鍵サイズ | ラウンド数 | セキュリティレベル | 用途 |
|---|---|---|---|
| AES-128 | 10 | 128ビット | 商用アプリケーション、TLS |
| AES-192 | 12 | 192ビット | 政府システム(SECRET) |
| AES-256 | 14 | 256ビット | TOP SECRET、金融セクター |
実用的なルール:モバイルアプリケーションではデフォルトでAES-256を使用します。AES-NI対応の最新デバイスでのAES-128とAES-256のパフォーマンス差は10~15%以下ですが、セキュリティレベルは2倍になります。量子分析(Grassl et al.、2016)によると、AES-128を破るにはグローバーのアルゴリズムで2^77の量子操作が必要ですが、AES-256には2^149が必要で、AES-256は今後20~30年間の量子攻撃に耐性があります。AES-128でさえ、大多数の商用シナリオに十分な保護を提供します:ブルース・シュナイアーの推定によると、128ビット鍵のブルートフォースには宇宙に存在するエネルギー以上のエネルギーが必要です。ただし、セキュリティ標準(GDPR、HIPAA、PCI DSS)はしばしば明示的にAES-256を要求するため、本番プロジェクトでは最大鍵長を使用する必要があります。
AESはブロック暗号として固定サイズ(128ビット)のブロックを暗号化します。任意長のデータを暗号化するには動作モードを使用します。モードの選択はセキュリティに重大な影響を与えます:間違ったモードはAESの強度を無効にする可能性があります。
モバイルプロジェクトでは、12バイトのnonceでAES-256-GCMを使用します。GCMはデータ暗号化と認証の2つの問題を同時に解決し、パディングオラクルや選択暗号文攻撃を防ぎます。Android KeystoreとiOS CryptoKitは追加の暗号プリミティブなしでAES-GCMをネイティブサポートします。GCMを使用する際は、同じ鍵でnonceを決して再利用しないことが重要です — これにより暗号化セキュリティが完全に破壊されます。暗号化ごとに新しいランダムなnonceを生成し、暗号文と一緒に保存します。
Jetpack Securityを使用したAndroidでの安全なAES-256-GCM実装の例を見てみましょう。以下のコードは完全なサイクルを示しています:MasterKeyによるAES-256鍵の作成、追加認証データ(AAD)を使用した文字列の暗号化と復号。
import androidx.security.crypto.MasterKey
import androidx.security.crypto.EncryptedSharedPreferences
val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
val securePrefs = EncryptedSharedPreferences.create(
context,
"secure_prefs",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
fun storeSecureData(key: String, value: String) {
securePrefs.edit().putString(key, value).apply()
}
fun readSecureData(key: String): String? {
return securePrefs.getString(key, null)
}
このソリューションの重要な特徴は、AES-256-GCMが2つのレベルで使用されることです:鍵-値ペア(PrefValueEncryptionScheme)の暗号化と、鍵名自体の保護(PrefKeyEncryptionSchemeはnonce再利用に耐性のあるAES-256-SIVを使用)。MasterKeyはAES-256-GCMアルゴリズムを使用して生成され、Trusted Execution Environmentを備えたデバイスではハードウェア保護されたAndroid Keystoreに保存されます。ハードウェアサポート(TEE)のないデバイスでは、鍵はBouncy Castleを介して暗号化され、SharedPreferencesに保存するよりも安全です。
大量のデータ(画像やファイルなど)を直接暗号化するには、AndroidX SecurityのEncryptedFileを介してAES-256-GCMを使用します。鍵のエクスポート(バックアップなど)には、PBKDF2と100000回以上の反復を使用したユーザーパスワードによる追加暗号化を使用します。
iOSでは、AES操作はCryptoKitフレームワーク(Swift 5.0+)を通じて編成されます。AES-256鍵はSymmetricKey(size: .bits256)を介して作成され、Secure Enclaveに保存されます — メインCPUとオペレーティングシステムから隔離されたハードウェア暗号プロセッサです。CryptoKitは2つのAES実装を提供します:AES.GCM(推奨)とAES.CBC(レガシーフォーマットとの後方互換性用)。暗号化はseal()メソッドを介して実行され、データ、鍵、nonce(12バイト)を受け取り、暗号文と認証タグを含む構造体AES.GCM.SealedBoxを返します。復号はopen()を介して行われます。AppleはCommonCryptoを直接使用しないことを強く推奨しています:CryptoKitは自動的に最適なパラメータを選択し、サイドチャネル攻撃から保護し、Apple SiliconプロセッサでAES-NIハードウェアアクセラレーションを使用します。Secure Enclaveを備えたデバイスでは、鍵はハードウェアモジュールから決して出ず、アプリケーションが完全に侵害されても盗難を防ぎます。鍵のシリアル化には、withUnsafeBytesメソッドを使用し、その後kSecAttrAccessible = kSecAttrAccessibleWhenUnlockedThisDeviceOnly属性でSecItemAddを介してKeychainに保存します。
よくある質問
AESは、秘密鍵を使用して読み取り可能なデータを読み取り不可能なバイトセットに変換するアルゴリズムです。データを元の形式に戻すには同じ鍵が必要です。AESは非常に信頼性が高く、米国政府の機密文書の暗号化に使用されています。
AES-128は128ビット鍵を使用し、10ラウンドの暗号化を実行します。AES-256は256ビット鍵と14ラウンドを使用し、破るのが2^128倍困難です。モバイルアプリケーションでは、パフォーマンス差が最小限であるためAES-256が推奨されます。
AES-256-GCMが最も安全で推奨されるモードです。GCMは認証付き暗号化(暗号化+整合性検証)を提供します。ECBモードは禁止されており、CBCは別途MACが必要です。GCMはモバイルアプリケーションのデファクト標準です。
理論的には、AESはブルートフォースで解読可能ですが、AES-256には2^256回の試行が必要です — 観測可能な宇宙の原子数よりも多い数です。AES-256に対する実用的な攻撃は存在しません。サイドチャネル攻撃(Spectre、Meltdown)はAESを破るのではなく、メモリから鍵を盗むため、ハードウェア鍵ストレージが重要です。
AndroidX Securityライブラリを使用します:KeyScheme.AES256_GCMのMasterKey.BuilderはAndroid Keystoreで保護された鍵を作成し、EncryptedSharedPreferencesはAES-256-GCMを介してすべてのデータを自動的に暗号化します。手動暗号化は不要 — APIはデフォルトで安全で、開発者エラーのリスクがありません。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。