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

ディフィー・ヘルマン鍵交換をPythonで実装|"盗聴されても"共通鍵を作る

2026-09-11実践

#ディフィーヘルマン#鍵交換#暗号#Python#実践

AESのような共通鍵暗号には「同じ鍵をどう安全に共有するか」という難問があります。その答えの一つが ディフィー・ヘルマン(DH)鍵交換通信を全部盗聴されても、共通の秘密鍵を作れる魔法のような手法です。Pythonで実装して驚きを体感しましょう。

発想:混ぜた色は分けられない

DHはよく「絵の具」でたとえられます。共通の色に、各自が秘密の色を混ぜて交換 → 受け取った色に自分の秘密をもう一度混ぜる。すると2人だけが同じ色にたどり着く。混ぜるのは簡単、分離は困難という非対称性が安全の源です。

公開のやり取りだけで秘密を共有

🎨

共通の素材

公開してOK

🔒

秘密を混ぜる

各自バラバラ

🤝

同じ鍵に到達

2人だけ

準備

Python標準ライブラリだけ(数式で本質を見ます)。

① 数式版DHを最小実装

数学では「絵の具」の代わりに**べき乗の余り(離散対数の困難性)**を使います。

# 公開パラメータ(全員が知ってOK)
p = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1  # 大きな素数
g = 2                                                    # 生成元

import secrets

# アリスとボブがそれぞれ秘密の数を用意
a = secrets.randbelow(p - 2) + 1    # アリスの秘密
b = secrets.randbelow(p - 2) + 1    # ボブの秘密

# 公開値を計算して交換(これは盗聴されてOK)
A = pow(g, a, p)     # アリス → ボブ
B = pow(g, b, p)     # ボブ → アリス

# 相手の公開値に自分の秘密を混ぜる
alice_key = pow(B, a, p)
bob_key   = pow(A, b, p)

print("鍵が一致?:", alice_key == bob_key)

出力は 鍵が一致?: True。公開値 A, B を盗聴者が見ても、秘密の a, b がわからなければ共通鍵は計算できません。これがDHの核心です。

🌱

盗聴者にできないこと

盗聴者は g, p, A, B を全部見られます。でも A=gᵃ から a を逆算するのが(大きな素数では)現実的に不可能。この「離散対数問題」の難しさが、鍵を守っています。

② 実務では鍵を派生させる

共有した数値はそのまま鍵に使わず、ハッシュで固定長の鍵にします。

import hashlib
shared = alice_key.to_bytes((alice_key.bit_length() + 7) // 8, "big")
aes_key = hashlib.sha256(shared).digest()   # AES用の256bit鍵に
print("AES鍵:", aes_key.hex()[:32], "...")

これでAES-GCMの鍵として使えます。

⚠️

中間者攻撃に注意

DHは「盗聴」には強いですが、通信に割り込む中間者攻撃(なりすまし)は単体では防げません。実際のTLSでは、DHにデジタル署名を組み合わせて相手が本物か確かめます。現代のTLSは前方秘匿性のためDHを標準採用しています。

まとめ

  • DH鍵交換は、公開のやり取りだけで共通の秘密鍵を作れる
  • べき乗の余り(離散対数の困難性)が安全の源
  • 共有値はハッシュで固定長の鍵に派生させて使う
  • 盗聴には強いが、中間者攻撃には署名との併用が必要

もう少し詳しく(背景と理論)

ディフィー・ヘルマン鍵交換は Diffie & Hellman (1976) が公開鍵暗号の概念とともに発表した、暗号史の転換点です1。安全性は離散対数問題の困難性に依存します。単体では通信に割り込む中間者攻撃(MITM)を防げないため、実際のTLSでは署名で相手を認証して併用します2。現代は計算効率と鍵長の面で**楕円曲線版(ECDH)が主流で、セッションごとに使い捨ての鍵を使う ephemeral(DHE/ECDHE)により、後に長期鍵が漏れても過去の通信を守る前方秘匿性(forward secrecy)**を実現します3。なお素数やパラメータの選択を誤ると Logjam のような攻撃を受けるため、標準化された安全なパラメータを使うのが鉄則です。

次の一歩 🌸

作った鍵で暗号化するAES実装、なりすまし対策のRSA署名、通信全体のHTTPSのしくみへどうぞ。

Footnotes

  1. Diffie, W. & Hellman, M. (1976). "New Directions in Cryptography." IEEE Trans. Information Theory, 22(6). 公開鍵暗号と鍵交換の概念を提示した記念碑的論文。

  2. DH は盗聴に強いが、能動的に割り込む中間者攻撃には無力。TLS では証明書・署名で相手の正当性を確かめてから鍵交換する。

  3. 使い捨て鍵の DHE/ECDHE は前方秘匿性を持ち、サーバー長期鍵が将来漏れても過去のセッションは復号されない。TLS 1.3 では前方秘匿な鍵交換が必須化された。

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

あわせて読みたい