PythonでRSAとECDSAの鍵ペアを扱う
署名と暗号化のためにRSA鍵とEC鍵を生成、シリアライズ、使用します。
「PythonでRSAとECDSAの鍵ペアを扱う」はCoddyKit上の無料Cryptology Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはCryptology Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Cryptology Academyコースには全4レッスンが含まれています。
鍵ペア操作の概要
Pythonのcryptographyライブラリは、鍵の生成、署名、検証、シリアライズ、読み込みのためにRSAとECDSAをサポートしています。これらは、TLS証明書、コード署名、JWTの基盤となる機能です。
RSA鍵ペアの生成
推奨される最小値は、互換性を重視する場合は2048ビット、長期間使用する鍵では4096ビットです。
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
public_key = private_key.public_key()
print("RSA key generated, size:", private_key.key_size, "bits")PSSを使ったRSA署名
署名には、PKCS#1 v1.5ではなく、必ずPSSパディングを使用してください。
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
message = b"document to sign"
signature = private_key.sign(
message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
print("RSA-PSS signature:", signature.hex()[:32], "...")RSA署名の検証
検証に失敗するとInvalidSignatureが発生します。
from cryptography.exceptions import InvalidSignature
try:
public_key.verify(
signature,
message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
print("Signature valid!")
except InvalidSignature:
print("Signature INVALID")ECDSA鍵ペアの生成
NIST P-256(secp256r1)を使用したECDSAは、RSA-3072よりはるかに小さい鍵で128ビットの安全性を実現します。
from cryptography.hazmat.primitives.asymmetric import ec
private_key = ec.generate_private_key(ec.SECP256R1())
public_key = private_key.public_key()
print("EC private key generated on curve:", private_key.curve.name)ECDSAの署名と検証
ECDSAはデフォルトでDERエンコードされた署名を使用します。
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography.exceptions import InvalidSignature
# Sign
sig = private_key.sign(b"my data", ec.ECDSA(hashes.SHA256()))
print("ECDSA signature bytes:", len(sig))
# Verify
try:
public_key.verify(sig, b"my data", ec.ECDSA(hashes.SHA256()))
print("ECDSA signature valid")
except InvalidSignature:
print("Invalid")鍵のPEMへのシリアライズ
保存または配布のために、鍵をPEMファイルへ保存します。
from cryptography.hazmat.primitives import serialization
# Private key — encrypted with passphrase
private_pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.BestAvailableEncryption(b"strong-passphrase")
)
# Public key — no encryption
public_pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
print(public_pem.decode()[:64])PEMからの鍵の読み込み
永続化した鍵をオブジェクトに読み戻します。
from cryptography.hazmat.primitives.serialization import (
load_pem_private_key, load_pem_public_key
)
with open("ec_private.pem", "rb") as f:
priv = load_pem_private_key(f.read(), password=b"strong-passphrase")
with open("ec_public.pem", "rb") as f:
pub = load_pem_public_key(f.read())
print("Loaded EC key curve:", priv.curve.name)ECDH鍵共有
ECDHを使用して、対称暗号化に使う共有秘密を導出します。
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
alice_priv = ec.generate_private_key(ec.SECP256R1())
bob_priv = ec.generate_private_key(ec.SECP256R1())
# Alice computes shared secret
shared = alice_priv.exchange(ec.ECDH(), bob_priv.public_key())
aes_key = HKDF(hashes.SHA256(), 32, None, b"app-context").derive(shared)
print("Derived AES key:", aes_key.hex())OAEPを使ったRSA暗号化
RSAで小さなデータ(例:DEK)を暗号化する場合は、必ずOAEPを使用してください。
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
# Encrypt with public key
ciphertext = public_key.encrypt(
b"small secret",
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
# Decrypt with private key
plaintext = private_key.decrypt(ciphertext, padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(), label=None
))
print("Decrypted:", plaintext)RSAとECDSAの選択
ECDSAは、P-256では約71バイト(RSA-2048では約256バイト)の小さい署名、より高速な署名処理、同等の安全性を提供します。RSAは、従来のシステムとの互換性が広く、理解しやすいという利点があります。新しいシステムではECDSA P-256またはEd25519を使用してください。
理解度チェック
デジタル署名では、なぜPKCS#1 v1.5よりRSA-PSSを優先すべきですか?
学習内容のまとめ
RSAにはrsa.generate_private_keyを、ECDSAにはec.generate_private_keyを使用してください。署名には、RSAではPSSを、ECDSAではECDSA + SHA-256を使用します。PKCS8形式とパスフレーズ暗号化を使用してPEMにシリアライズしてください。鍵共有にはECDHを使用します。新しいシステムではECDSA P-256またはEd25519を優先してください。
よくある質問
「PythonでRSAとECDSAの鍵ペアを扱う」レッスンは無料ですか?
はい。「PythonでRSAとECDSAの鍵ペアを扱う」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Cryptology Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Cryptology Academyコースには全4レッスンが含まれています。
「PythonでRSAとECDSAの鍵ペアを扱う」で何を学びますか?
署名と暗号化のためにRSA鍵とEC鍵を生成、シリアライズ、使用します。 ブラウザで直接実行するハンズオンコードでCryptology Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Cryptology Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのCryptology Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「PythonでRSAとECDSAの鍵ペアを扱う」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このCryptology Academyレッスンでコードを書いて実行できますか?
はい。すべてのCryptology Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Python cryptographyライブラリの概要
- PythonでAES-GCMを暗号化・復号化する
- PythonでRSAとECDSAの鍵ペアを扱う
- Python暗号でよくある落とし穴と安全なパターン