Shared key generation from EC with pycryptodome

Question:

I’m curently working on a project were i need to compute an hkdf symetric key.
To do that i need to generate a shared secret from the private key and an ephemeral public key.

For the rest of my work i did use pycryptodome but i can’t find in the doc if it allow generation of shared secret. I saw in the futur plan their intention to add Elliptic Curves (ECIES, ECDH) since ecdh is based on shared key it wouldn’t be suprising if shared key generation is not implemented yet.

I tried using the cryptography lib too but impossible to load my ephemeral key.

from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec

def __compute_shared_secret(ephemeral_public_key: bytearray) -> bytes:
    client_public_key = serialization.load_der_public_key(ephemeral_public_key)
    server_private_key = serialization.load_der_private_key(b"my_private", password=None)
    shared_secret = server_private_key.exchange(ec.ECDH(), client_public_key)
    return shared_secret
Could not deserialize key data. The data may be in an incorrect format or it may be encrypted with an unsupported algorithm.

ephemeral_public_key is base64 encoded and given by the gpay api.

i would like to know if i can do it with pycryptodome and if not if using the cryptography lib only for this part is a good idea.

Asked By: Bastien B

||

Answers:

With help of @Topaco i ended up making this function:

from cryptography.hazmat.primitives.asymmetric.ec import ECDH
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePublicKey
from cryptography.hazmat.primitives.asymmetric.ec import SECP256R1
from cryptography.hazmat.primitives.serialization import load_pem_private_key

def __compute_shared_secret(ephemeral_public_key: bytes) -> bytes:
    curve = SECP256R1()
    public_key = EllipticCurvePublicKey.from_encoded_point(curve, ephemeral_public_key)
    server_private_key = load_pem_private_key(b'<private_key>', password=None)
    shared_secret = server_private_key.exchange(ECDH(), public_key)
    return shared_secret

It work juste fine

Answered By: Bastien B