ECDH 密钥交换——示例
现在用 Python 实现 ECDH 算法(椭圆曲线 Diffie–Hellman 密钥交换)。
我们将使用 Python 的 ECC 库 tinyec:
pip install tinyec
现在生成两个公私密钥对,交换公钥并计算共享秘密:
from tinyec import registry
import secrets
def compress(pubKey):
return hex(pubKey.x) + hex(pubKey.y % 2)[2:]
curve = registry.get_curve('brainpoolP256r1')
alicePrivKey = secrets.randbelow(curve.field.n)
alicePubKey = alicePrivKey * curve.g
print("Alice public key:", compress(alicePubKey))
bobPrivKey = secrets.randbelow(curve.field.n)
bobPubKey = bobPrivKey * curve.g
print("Bob public key:", compress(bobPubKey))
print("Now exchange the public keys (e.g. through Internet)")
aliceSharedKey = alicePrivKey * bobPubKey
print("Alice shared key:", compress(aliceSharedKey))
bobSharedKey = bobPrivKey * alicePubKey
print("Bob shared key:", compress(bobSharedKey))
print("Equal shared keys:", aliceSharedKey == bobSharedKey)
运行上述代码示例:https://repl.it/@nakov/ECDH-Key-Exchange-in-Python。
ECDH 计算使用的椭圆曲线是 256 位命名曲线 brainpoolP256r1。私钥为 256 位(64 个十六进制数字),且随机生成。由于进行了密钥压缩,公钥将是 257 位(65 个十六进制数字)。
上述代码的输出如下:
Alice public key: 0x66c808e6b5be6d6620934bc6ffa2b8b47f9786c002bfb06d53a0c27535641a5d1
Bob public key: 0x7d15195432d1ac7f38aeb054d07d9b2e1faa913b78ad04d5efdd4a1ee8d9a3191
Now exchange the public keys (e.g. through Internet)
Alice shared key: 0x90f5a1cf2ed1dbb0322178df6bb0dd72c541884618b2989a3e5e663198667a621
Bob shared key: 0x90f5a1cf2ed1dbb0322178df6bb0dd72c541884618b2989a3e5e663198667a621
Equal shared keys: True
由于存在随机性,每次运行上述代码时,密钥都会不同,但最终为 Alice 和 Bob 计算出的共享秘密始终相同。生成的共享秘密是一个 257 位整数(256 位曲线的压缩 EC 点,编码为 65 个十六进制数字)。