0Pricing
Java Academy · レッスン

AES共通鍵暗号

Javaのjavax.crypto APIを使い、AES/CBC/PKCS5Paddingで機密データを暗号化・復号します。

「AES共通鍵暗号」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

対称暗号と非対称暗号

対称暗号では暗号化と復号に同じ鍵を使用します(高速で、大量データに適しています)。非対称暗号では公開鍵と秘密鍵のペアを使用します(低速ですが、鍵交換や署名に使用されます)。AES は標準的な対称暗号です。

AES のモード: CBC と GCM

AES には複数のモードがあります。AES/CBC/PKCS5Padding は一般的ですが、認証機能がありません。AES/GCM/NoPadding は暗号化と認証の両方(AEAD)を提供するため、新しいコードでは強く推奨されます。

AES 鍵の生成

KeyGenerator を使用して、256 ビットの AES 鍵を安全に生成します。

KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(256); // 256-bit key
SecretKey key = kg.generateKey();
// Persist the key:
String b64Key = Base64.getEncoder().encodeToString(key.getEncoded());
// Restore the key:
byte[] decoded = Base64.getDecoder().decode(b64Key);
SecretKey restored = new SecretKeySpec(decoded, "AES");

AES/GCM 暗号化

GCM モードでは、暗号化ごとに一意の 12 バイトの初期化ベクトル(IV)が必要です。暗号化処理のたびに新しいランダムな IV を生成してください。同じ鍵で IV を再利用してはいけません。

byte[] iv = new byte[12]; // 96-bit IV for GCM
new SecureRandom().nextBytes(iv);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(128, iv); // 128-bit auth tag
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte[] ciphertext = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
// Transmit/store: IV + ciphertext (IV is not secret)

AES/GCM 復号

保存されたデータから IV を取り出し、spec を再構成して復号します。GCM は真正性を自動的に検証するため、改ざんされたデータでは AEADBadTagException がスローされます。

// Assume stored = iv + ciphertext:
byte[] iv         = Arrays.copyOfRange(stored, 0, 12);
byte[] ciphertext = Arrays.copyOfRange(stored, 12, stored.length);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv));
byte[] plaintext = cipher.doFinal(ciphertext); // throws if tampered

暗号文と一緒に IV を保存する

IV は秘密ではないため、暗号文の先頭に付加するか、暗号文と一緒に保存します。受信側は復号に IV を必要とします。鍵は秘密に保管する必要があります。

byte[] encryptedData = new byte[iv.length + ciphertext.length];
System.arraycopy(iv,         0, encryptedData, 0,          iv.length);
System.arraycopy(ciphertext, 0, encryptedData, iv.length, ciphertext.length);
String b64 = Base64.getEncoder().encodeToString(encryptedData);

パスワードからの鍵導出(PBKDF2)

パスワードを AES 鍵として直接使用してはいけません。エントロピーが低すぎるためです。ランダムなソルトと高い反復回数を使用して、PBKDF2 で鍵を導出します。

PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 310_000, 256);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
byte[] keyBytes = skf.generateSecret(spec).getEncoded();
SecretKey key = new SecretKeySpec(keyBytes, "AES");

Java Security Provider の使用

JDK のデフォルトプロバイダーは AES を処理します。追加のアルゴリズムや FIPS 準拠が必要な場合は、Bouncy Castle プロバイダーを使用します。

// With Bouncy Castle:
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");

エンベロープ暗号化パターン

ランダムに生成したデータ暗号化鍵(DEK)でデータを暗号化します。AWS KMS や HashiCorp Vault などの KMS に保存した鍵暗号化鍵(KEK)で DEK を暗号化します。これにより、鍵が露出する範囲を限定できます。

Spring アプリケーションでの AES

Spring Security の TextEncryptor または Spring Security Crypto モジュールを使用すると、Cipher や IV を手動で管理せずに、高水準の AES 暗号化を利用できます。

TextEncryptor encryptor = Encryptors.text(password, salt);
String encrypted = encryptor.encrypt("sensitive data");
String decrypted = encryptor.decrypt(encrypted);

よくある落とし穴

同じ鍵で IV を再利用すること、ECB モードを使用すること(パターンが保持されます)、パスワードを鍵として直接使用すること、認証タグを無視することは、決して行わないでください。新しいコードでは必ず GCM を使用します。

確認問題

AES/CBC にはなく、AES/GCM にある機能は何ですか。

まとめ

認証付き暗号化には AES/GCM/NoPadding を使用します。暗号化ごとに新しいランダムな 12 バイトの IV を生成します。IV は暗号文の先頭に付加します。パスワードからは PBKDF2 で鍵を導出します。同じ鍵で IV を再利用してはいけません。

よくある質問

「AES共通鍵暗号」レッスンは無料ですか?

はい。「AES共通鍵暗号」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「AES共通鍵暗号」で何を学びますか?

Javaのjavax.crypto APIを使い、AES/CBC/PKCS5Paddingで機密データを暗号化・復号します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「AES共通鍵暗号」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. MessageDigestによる暗号学的ハッシュ
  2. AES共通鍵暗号
  3. メッセージ完全性のためのHMAC-SHA256
  4. JWT:構造、生成、検証
← Java Academyに戻る