Currently I started working with the cryptography framework on python. I'm trying to build a SSH Suit by my own but I ran into some problem with the library. I'm trying to build my own Elliptic Curve Key Exchange Init Packet (with scapy).
I'm trying to do an Elliptic Curve Diffie-Hellman key exchange with the curve secp256r1. I'm able to generate the key-pair on my client with out any problem. But after I created the public key object im kinda confused how to get the 32-byte public key for exchange via network packets.
my code so far (which doesn't work for me): from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serilization
curve = SECP256R1()
peer_private_key = ec.generate_private_key(curve)
peer_public_key = peer_private_key.public_key()
peer_public_pkt = peer_public_key.public_bytes(encoding=serilization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo)
But this peer_public_pkt is not 32 Byte long.
Another Problem is when i get like an ECDH Public Key Value via Scapy or Wireshark from a Server via Network i cant translate the value back with
srv_public_key = ec.EllipticCurvePublicKey.from_encoded_point(curve, data_from_wireshark)
I think I'm missing some crucial steps here but I looked at the documentation for two hours and into some older examples on different sites but I can't find help (or see the solution).
Hopefully you can help me :). If something about my problem is not clear just ask.
EllipticCurvePublicKey.from_encoded_point
takes compressed/uncompressed points. You can obtain those from public_bytes
via a format of PublicFormat.CompressedPoint
and format of Encoding.X962
. SubjectPublicKeyInfo DER serialization is an ASN.1 format with additional structure.
Your assumption of 32 bytes on a secp256r1 key is also incorrect, as a compressed public point adds one byte defining the sign for unambiguous point reconstruction.