Sec-02: 基本的な暗号化(AES-256-GCM)
javax.crypto を使って AES-256-GCM による暗号化・復号を実装します。 IV(Initialization Vector:初期化ベクトル)のランダム生成と、GCM モードによる改ざん検出も解説します。
なぜデータを暗号化するのか
データベースや外部ストレージに機密情報(個人情報・クレジットカード番号・APIキーなど)を 保存する場合、平文(そのままの形)で保存するのは危険です。 データベースが漏えいした場合に情報がそのまま読み取られてしまいます。 暗号化することで、鍵を持たない攻撃者からデータを保護できます。
AES-256-GCM の特徴
- AES-256: AES(Advanced Encryption Standard:高度暗号化標準)は現在最も広く使われている共通鍵暗号方式です。 256 ビットの鍵長は現在の技術では解読が事実上不可能です。
- GCM モード(Galois/Counter Mode:ガロア/カウンタモード): 暗号化と同時にデータの完全性(改ざん検出)も保証します。 復号時にデータが改ざんされていると例外が発生するため、通信途中の改ざんを検出できます。 これを「認証付き暗号化(AEAD)」と呼びます。
- IV(Initialization Vector:初期化ベクトル): 同じ平文を同じ鍵で暗号化しても毎回異なる暗号文になるよう、 ランダムな初期値を付加します。GCM では 12 バイトの IV が推奨されています。 IV は秘密にする必要はありませんが、同じ鍵で IV を再利用してはいけません。
サンプルコード
Java 8 から AES/GCM/NoPadding が標準ライブラリで利用できます。IV(Initialization Vector:初期化ベクトル)は毎回 SecureRandom で生成し、暗号文の先頭に付与して保存します。
よくあるミス・注意点
⚠️ IV(初期化ベクトル)を固定値にする
同じ鍵と IV の組み合わせで複数の平文を暗号化すると、暗号文のパターンから元のデータが解析されるリスクがあります。 GCM モードでは特に危険で、鍵の安全性が完全に崩れる場合があります。 IV は必ず SecureRandom で 暗号化のたびにランダム生成し、暗号文と一緒に保存してください。
⚠️ ECB モードを使う
ECB(Electronic Codebook)モードは同じ平文ブロックが常に同じ暗号文ブロックになります。 そのため、データ中のパターンが暗号文にも現れてしまいます(例: 同じ内容のブロックが同じ暗号文になる)。AES/ECB/PKCS5Padding は使わず、 必ず AES/GCM/NoPadding を使いましょう。
⚠️ 鍵をソースコードにハードコードする
暗号化の鍵をソースコード中に直接書くと、Git リポジトリに機密情報が残ります。 一度コミットされたシークレットは履歴から消すのが困難です。 鍵は環境変数・Vault・KMS(Key Management Service)などの安全な場所で管理し、 実行時に読み込む設計にしてください。
⚠️ IV を暗号文とは別に管理する
IV は復号時に必要です。暗号文とは別のカラムに保存するなど管理が複雑になりがちです。 本サンプルのように暗号文の先頭 12 バイトに IV を付与して一緒に保存すると、 管理が簡単になります。IV は秘密情報ではないので、暗号文と一緒に保存して問題ありません。
テストする観点
- 暗号化 → 復号を行うと元のテキストと一致すること(往復変換)
- 日本語・マルチバイト文字を含むテキストが正しく暗号化・復号できること
- 同じ平文を同じ鍵で2回暗号化した場合に、異なる暗号文が生成されること(IV のランダム性)
- 改ざんした暗号文(バイト列を1バイト変更)を復号すると例外が発生すること(GCM の改ざん検出)
- 異なる鍵で復号しようとすると例外が発生すること
- 空文字列が正常に暗号化・復号できること(境界値)
- 非常に長いテキストが正常に暗号化・復号できること(境界値)