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

デジタル署名をPythonで実装する|RSAで「改ざん」を見抜くしくみ

2026-09-02実践

#RSA#デジタル署名#公開鍵暗号#Python#実践

「このメッセージは本人が書いた」「途中で書き換えられていない」——これを保証するのがデジタル署名です。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のしくみ、将来の話は耐量子暗号へどうぞ。

Footnotes

  1. Rivest, R., Shamir, A. & Adleman, L. (1978). "A Method for Obtaining Digital Signatures and Public-Key Cryptosystems." Communications of the ACM, 21(2).

  2. 署名は RSASSA-PSS(確率的パディング、RFC 8017)が推奨。生のRSAや古いPKCS#1 v1.5は偽造・改ざんのリスクがある。

  3. Shor のアルゴリズムは素因数分解を多項式時間で解く。NIST は耐量子署名(ML-DSA 等)を標準化し、移行が始まっている。

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

あわせて読みたい