はじめに
Python で暗号処理を実装するとき、自作実装はほぼ確実に事故ります。
それを防ぐために存在するのが PyCryptodome です。
PyCryptodome は、かつて広く使われていた PyCrypto の正統後継であり、
- 現代的な暗号アルゴリズム
- 安全なデフォルト設計
- 継続的なメンテナンス
を備えた、実戦投入できる暗号ライブラリです。
暗号の世界の格言
「Don’t roll your own crypto」
→ PyCryptodome を使え、という意味です。
PyCryptodome でできること一覧
共通鍵暗号(Symmetric Encryption)
- AES(CBC / GCM / EAX)
- ChaCha20 / Salsa20
実務では AES-GCM / AES-EAX 一択
(暗号化+改ざん検知を同時に提供)
公開鍵暗号(Asymmetric Encryption)
- RSA(暗号化・署名)
- ECC / ECDSA / Ed25519
- 鍵生成・PEM 出力・読み込み
「RSA 鍵が数字じゃない問題」は後で解説します。
ハッシュ & MAC
- SHA-256 / SHA-3
- BLAKE2
- HMAC
HMAC を使えば
Length Extension Attack は成立しません(重要)
パスワードハッシュ(KDF)
- PBKDF2
- bcrypt
- scrypt
MD5 / SHA-1 は論外
パスワードは必ず KDF を使います。
インストール方法
pip install pycryptodome
実践① AES-GCM
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
key = get_random_bytes(32) # 256-bit
cipher = AES.new(key, AES.MODE_GCM)
ciphertext, tag = cipher.encrypt_and_digest(b"secret message")
nonce = cipher.nonce
なぜ GCM が良いのか?
- 暗号化(Confidentiality)
- 改ざん検知(Integrity)
- 復号失敗時は即エラー(安全)
CBC + MAC を自分で組み合わせる必要なし
実践② RSA 鍵生成と「数字じゃない問題」
from Crypto.PublicKey import RSA
key = RSA.generate(2048)
private_key = key.export_key()
public_key = key.publickey().export_key()
print(private_key.decode())
print(public_key.decode())
なぜ RSA 鍵は文字列なのか?
出力例:
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQ...
これは:
- 中身:巨大な整数(n, e, d, p, q…)
- 外側:ASN.1 + Base64(PEM形式)
人間が扱いやすいようにエンコードされているだけ
数学的には、ちゃんと「数字の塊」です。
実践③ パスワードハッシュ(PBKDF2)
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Random import get_random_bytes
salt = get_random_bytes(16)
key = PBKDF2(
password="password",
salt=salt,
dkLen=32,
count=200_000
)
なぜ普通の hash() ではダメ?
- 高速すぎる → 総当たりに弱い
- ソルトなし → レインボーテーブル即死
KDF は「わざと遅くする」ための仕組み
よくある危険パターン
| パターン | なぜ危険か |
|---|---|
| AES-ECB | パターンが丸見え |
| 自前 CBC + 自前 MAC | 実装ミス地獄 |
| hash(password) | 総当たり余裕 |
| nonce 再利用 | GCM 即死亡 |
正しい選択
- AES-GCM / AES-EAX
- RSA/ECC はライブラリ任せ
- パスワードは PBKDF2 / bcrypt / scrypt
- nonce / salt は毎回ランダム
まとめ
PyCryptodome は、
「暗号を正しく、楽に、安全に使わせる」ための道具
です。
暗号は賢く作るものではなく、
賢く「使う」ものです。