手を振るまもるくんゆるふわサイバーセキュリティ
監視中のまもるくん

Python AES暗号化とは|cryptographyでAES-GCMを実装する

2026-09-10 ・ 実践

#AES#暗号化#共通鍵#Python#実践

Python AES暗号化とは、cryptography ライブラリの AESGCM クラスを使って、共通鍵暗号 AES を改ざん検知までできる AES-GCM(認証付き暗号)方式で暗号化することです。送り手と受け手が同じ秘密鍵を持つ共通鍵暗号で、暗号化・復号・改ざん検知のすべてをこの1クラスでカバーできます。まずは最短のコードで全体の流れを見てから、各ステップを詳しく説明します。

この記事で分かること

  • AES-GCMは、共通鍵暗号AESを「暗号化と改ざん検知を同時に行う認証付き暗号(AEAD)」として使うモードで、鍵・nonce・暗号文がそろわないと復号できないこと
  • nonce(12バイトのランダム値)は同じ鍵で絶対に使い回してはいけない。使い回すとGCMの安全性そのものが崩れること
  • 暗号文が1バイトでも改ざんされていると、復号時にInvalidTag例外が発生して拒否されること

対象読者:Pythonで保存データや通信内容を暗号化し、改ざん検知まで実装したいエンジニアの方

執筆:ゆるふわセキュリティ編集部 最終更新日:2026年10月28日

AES-GCM暗号化の流れ

🔑

鍵生成

AESGCM.generate_key

→
🎲

nonce

毎回ランダムな12バイト

→
🔒

暗号化

encrypt(nonce, 平文, aad)

→
🔓

復号

decrypt(nonce, 暗号文, aad)

Python
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
 
key = AESGCM.generate_key(bit_length=256)
aesgcm = AESGCM(key)
nonce = os.urandom(12)
 
ciphertext = aesgcm.encrypt(nonce, b"hello", None)
print(aesgcm.decrypt(nonce, ciphertext, None))   # b'hello'

鍵(key)とnonceがそろえば複合でき、途中で暗号文が1バイトでも書き換えられていれば復号時に例外で拒否されます。以降で、鍵の管理やnonceの扱い方まで含めて詳しく見ていきます。

AES-GCMを選ぶ理由

AESには複数の「使い方(モード)」があります。中でも GCM は暗号化と同時に改ざん検知もしてくれる「認証付き暗号(AEAD)」。今どきの推奨はこれ一択です。

💡

共通鍵 = 同じ鍵で暗号化も復号も

AESは送り手も受け手も同じ秘密鍵を持ちます(公開鍵暗号とは別物)。鍵をどう安全に共有するかが課題で、そこは鍵交換や公開鍵暗号が担います。

準備

ターミナル
pip install cryptography

① 鍵とnonceを用意して暗号化

Python
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
 
key = AESGCM.generate_key(bit_length=256)   # 256bitの共通鍵
aesgcm = AESGCM(key)
 
nonce = os.urandom(12)                       # 毎回ランダムな12バイト
plaintext = b"社外秘: 新製品は3月発表"
aad = b"context-v1"                          # 認証だけする付加データ(任意)
 
ciphertext = aesgcm.encrypt(nonce, plaintext, aad)
print("暗号文(hex):", ciphertext.hex()[:48], "...")

② 復号する

Python
decrypted = aesgcm.decrypt(nonce, ciphertext, aad)
print("復号:", decrypted.decode())            # 社外秘: 新製品は3月発表

同じ鍵・nonce・aadがそろって初めて復号できます。

③ 改ざんは検知される

暗号文を1バイトでも書き換えると、復号は例外で拒否されます。

Python
from cryptography.exceptions import InvalidTag
 
tampered = bytearray(ciphertext); tampered[0] ^= 1   # 1ビット改ざん
try:
    aesgcm.decrypt(nonce, bytes(tampered), aad)
except InvalidTag:
    print("改ざん検知!復号を拒否しました")

出力は 改ざん検知!復号を拒否しました。GCMは暗号化と改ざん検知を同時に担うので、「復号できたのに中身が偽物」という事故を防げます。

⚠️

nonceは使い回さない

同じ鍵で同じnonceを2回使うと、GCMの安全性は崩壊します。nonceは**毎回ランダム(またはカウンタで一意)**にすること。鍵はもちろん秘密に、環境変数やシークレット管理で扱います。

まとめ

  • AES-GCMは暗号化と改ざん検知を同時に行う認証付き暗号
  • 共通鍵(送受で同じ鍵)+毎回ランダムなnonceで暗号化
  • 鍵・nonce・aadがそろわないと復号できない
  • 改ざんはInvalidTagで拒否される。nonce使い回しは厳禁

よくある質問

Q. AESの鍵は128bitと256bit、どちらを使えばいい?

A. 新規に実装するなら256bitを選べば安全側に倒せます。AESGCM.generate_key(bit_length=256)のように指定します。128bitも現時点で破られていませんが、長期間保存するデータや規制で256bitを求められる場合は256bitを選びます。

Q. GCM以外のモード(CBCなど)を使ってはいけない?

A. 新しく書くコードではGCM(またはChaCha20-Poly1305)を選ぶのが現在の推奨です。CBCモード単体には改ざん検知がなく、別途HMACを組み合わせる実装が必要になるため、間違えると脆弱になりやすいからです。

Q. aad(付加データ)は必ず指定する必要がある?

A. 必須ではありません。暗号化しないが改ざんだけ検知したいデータ(送信先IDやバージョン番号など)がある場合に使います。不要なら本記事の最短コードのようにNoneを渡せます。

📚 もう少し詳しく(背景と理論)気になる人向け・タップで開く

AES は2001年に NIST が標準化した共通鍵暗号で、公募で選ばれた Rijndael が実体です(FIPS 197)1。ブロック長128bit、鍵長は128/192/256bit。ここで使った GCM モードは、暗号化と改ざん検知を同時に行う認証付き暗号(AEAD)で、その方式は NIST SP 800-38D で規定されています2。

実装上の最重要ポイントは nonce(IV)を鍵ごとに絶対に再利用しないこと——GCM で nonce を使い回すと認証鍵が漏れ、機密性・完全性が同時に崩壊します3。素の AES(ECB/CBC 単体、認証なし)はパディングオラクル等の攻撃対象になりうるため、現代は AEAD が推奨です。

次の一歩 🌸

鍵をどう共有するかはディフィー・ヘルマン鍵交換、暗号の全体像は暗号の基礎、鍵の保管はシークレット管理へどうぞ。

参考資料・出典

ゆるふわポータルでは、一次情報・公的資料にもとづき、専門用語をできるだけやさしく翻訳することを心がけています。内容に誤りや古い情報がある場合は、お問い合わせからご連絡ください。

執筆:ゆるふわセキュリティ編集部 最終更新日:2026年10月28日

Footnotes

  1. NIST FIPS 197 (2001, 2023改訂). "Advanced Encryption Standard (AES)." Rijndael(Daemen & Rijmen)をベースに標準化。 ↩

  2. NIST SP 800-38D. "Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC." 認証タグで改ざんを検知する AEAD。 ↩

  3. GCM の nonce 再利用は致命的(Joux の "forbidden attack")。ランダム96bit nonce か、確実に一意なカウンタを使う。鍵はシークレット管理で厳重に扱う。 ↩

この記事をシェア:𝕏 で共有LINEで送る

🔥 この分野の最新トレンドをチェック →

あわせて読みたい