Crypto++ 和 Python 之间的 Diffie-Hellman 密钥交换

Diffie-Hellman key exchange between Crypto++ and Python

考虑客户端和服务器之间的 Diffie-Hellman 密钥交换,其中客户端应用程序是用 c++ 编写的,后端是用 python 编写的。 客户端应用程序使用 Crypto++ lib for crypto stuff and Python uses cryptography.

此处是客户端应用程序部分,其中私有密钥和 public 密钥生成

//domain parameters
OID CURVE = secp256k1();
AutoSeededX917RNG<AES> rng;
ECDH < ECP >::Domain dhA(CURVE);

// application private and publik key
SecByteBlock privA(dhA.PrivateKeyLength()), pubA(dhA.PublicKeyLength());
std::string privB64(R"(P3VfVpnSYcKQWX+6EZOly2XKy6no4UAB0cQhjBfyBD4=)");
privA.Assign(reinterpret_cast<const byte*>(FromB64(privB64).c_str()), dhA.PrivateKeyLength());
dhA.GeneratePublicKey(rng, privA, pubA);

// serializa public key into integer
Integer intPub;
intPub.Decode(pubA.BytePtr(), pubA.SizeInBytes());
std::string ret;
intPub.DEREncode(CryptoPP::StringSink(ret));
std::cout << ToB64(ret);// the output is loaded into python

现在的问题是我不知道如何将 public 密钥反序列化为 python EllipticCurvePublicKey. When I use cryptography.hazmat.primitives.serialization.load_der_public_key() 我得到

ValueError: Could not deserialize key data

有人尝试使用这两个库在 Crypto++ 和 Python 之间实现 Diffie-Hellman 密钥交换吗?

问题是当序列化数据以某种方式传输到后端时如何使用 Python EllipticCurvePublicKey 类型接口恢复它。即使我决定使用 protobuf,也会出现同样的问题。

但现在我找到了解决方案,如果有人也会遇到这个问题,我会把它放在这里。

我发现没有直接从 Crypto++ SecByteBlock 序列化对象(代表 Diffie-Hellman public 键)加载 Python EllipticCurvePublicKey 对象的接口在此范围内)。

为此,我们需要将 public 键转换为椭圆曲线点,并按照您在这段代码中看到的方式序列化点的每个坐标(这是一个大整数):

CryptoPP::DL_GroupParameters_EC<ECP> params(CURVE);    
CryptoPP::ECPPoint p = params.DecodeElement(pubA.BytePtr(), true);
std::cout << CryptoPP::IntToString(p.x) << std::endl;// this will be send to backend
std::cout << CryptoPP::IntToString(p.y) <<std::endl;

要将 Python 代码中的两个整数(点的 x 和 y 坐标)恢复为 DH public 密钥,您需要执行以下操作

# assuming that the x and y values are from client side 
x = 109064308162845536717682288676453496629093274218806834681903624047410153913758
y = 63162707562199639283552673289102028849183508196715869820627148926667819088660
peer_public_key =cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicNumbers(x, y, ec.SECP256K1()).public_key(default_backend())