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

时间:2018-02-14 09:23:10

标签: python c++ crypto++ diffie-hellman python-cryptography

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

此处私有和公钥生成的客户端应用程序部分

//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

现在的问题是,我不知道如何将公钥反序列化为python EllipticCurvePublicKey。当我使用cryptography.hazmat.primitives.serialization.load_der_public_key()时 我得到了

ValueError: Could not deserialize key data

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

1 个答案:

答案 0 :(得分:2)

The issue was when serialized data in some way was transferred to backend how to recover it with Python EllipticCurvePublicKey type interface. Even if I decide to use protobuf the same question would arise.

But now I found the solution I'll put it here if anyone also will encounter this issue.

As I find out there is no interface to directly load Python EllipticCurvePublicKey object from Crypto++ SecByteBlock serialized object (which is representing the Diffie-Hellman public key in this scope).

To do this we need to convert public key into elliptic curve point and the serialize each coordinate of point (which is a big integer) in the way as you can see in this code snipped:

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;

To recover the two integers (x and y coordinates of the point) in the Python code as a DH public key you need to do the following

# 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())