
デジタル署名をPythonで実装する|RSAで「改ざん」を見抜くしくみ
2026-09-02 ・ 実践
「このメッセージは本人が書いた」「途中で書き換えられていない」——これを保証するのがデジタル署名です。HTTPSもソフトウェア配布もこの仕組みで守られています。この記事ではPythonのcryptographyライブラリで、RSA署名を実際に作って検証し、改ざんをコードで検知するところまでやります。
発想: 秘密鍵で署名、公開鍵で検証
暗号化とは逆向きに鍵を使います。送信者だけが持つ秘密鍵で署名を作り、誰でも持てる公開鍵で検証する。秘密鍵を持つ本人しか正しい署名を作れないので、本人性と改ざん検知が同時に成り立ちます。
署名と検証の流れ
署名
秘密鍵で作る
送信
本文+署名
検証
公開鍵で確かめる
🗝️ 公開鍵暗号を体験
「公開鍵」でかけた暗号は、対になる「秘密鍵」でしか開けません。試してみましょう
公開鍵(かける鍵)は配ってOK。秘密鍵を持つ本人だけが開けられる——これがHTTPSやパスキーを支える仕組みです
準備
pip install cryptography
① 鍵ペアを作る
RSAの秘密鍵と、そこから公開鍵を取り出します。
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
65537 って何?
public_exponent=65537 は公開指数eの定番値です。計算効率と安全性のバランスが良く、実務のRSAはほぼこの値。key_size=2048 は鍵の強度で、現在の推奨最低ラインです。
② 秘密鍵で署名する
メッセージのハッシュに対して署名します。
message = b"Maru -> Bob: 契約Aを承認します"
signature = private_key.sign(
message,
padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),
hashes.SHA256(),
)
print("署名の長さ:", len(signature), "バイト") # 256バイト
③ 公開鍵で検証する
検証は「正しければ何も起きない、ダメなら例外」というAPIです。真偽を返す関数にラップします。
from cryptography.exceptions import InvalidSignature
def verify(pub, msg, sig):
try:
pub.verify(
sig, msg,
padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH),
hashes.SHA256(),
)
return True
except InvalidSignature:
return False
print(verify(public_key, message, signature)) # True
print(verify(public_key, b"Maru -> Bob: 契約Bを承認します", signature)) # False
正しい本文なら True、「A」を「B」に変えただけの本文は False。1文字変わっただけでハッシュが激変し、署名が合わなくなる——これが改ざん検知の正体です。
なぜ1文字で崩れるのか
署名はメッセージそのものではなく、その「ハッシュ値」に対して作られます。ハッシュは入力が少しでも変わると出力が全く別物になる(雪崩効果)。だから改ざんは必ずバレます。ハッシュの性質は暗号の基礎で解説しています。
署名 ≠ 暗号化
よくある誤解を整理します。
- 暗号化 = 中身を秘密にする(公開鍵で暗号化 → 秘密鍵で復号)
- 署名 = 本人性と改ざん検知(秘密鍵で署名 → 公開鍵で検証)
鍵の使う向きが逆です。用途が違うので混同しないようにしましょう。
RSAの将来
RSAの安全性は「大きな数の素因数分解が難しい」ことに依存しています。十分大きな量子コンピュータが実現すると破られる恐れがあり、耐量子暗号(PQC)への移行が始まっています。
まとめ
- デジタル署名=秘密鍵で署名し、公開鍵で検証する
- 本人性(なりすまし防止)と改ざん検知を同時に実現する
- 署名は本文のハッシュに対して作られるので、1文字の改ざんも見抜ける
- 署名と暗号化は鍵の向きが逆。用途を混同しない
もう少し詳しく(背景と理論)
RSA は Rivest・Shamir・Adleman (1978) が発表した公開鍵暗号で、安全性は巨大な合成数の素因数分解の困難性に依存します1。署名では秘密鍵で「署名」し、公開鍵で誰でも検証できる——これで本人性と改ざん検知を同時に保証します。実装では生のRSAをそのまま使わず、PSS などのパディング方式を用いるのが必須です(教科書的RSAは決定論的で攻撃に弱い)2。鍵長は現在2048bit以上が推奨で、将来的には量子コンピュータ(Shorのアルゴリズム)が素因数分解を破る脅威があるため、耐量子暗号(PQC)への移行が国際的に進んでいます3。
次の一歩 🌸
暗号の土台は暗号の基礎、通信でどう使われるかはHTTPSのしくみ、将来の話は耐量子暗号へどうぞ。