def pubkey_from_xml(xml): root = ET.fromstring(xml) x = int(root[1][0].attrib['Value']) y = int(root[1][1].attrib['Value']) return EllipticCurvePublicNumbers( x, y, SECP521R1()).public_key(backend=default_backend())
def pubkey_from_json(json_pubkey): root = json.loads(json_pubkey.decode()) x = int(root['x'], 16) y = int(root['y'], 16) return EllipticCurvePublicNumbers(x, y, SECP521R1()).public_key(backend=default_backend())
def __init__(self, xml): logging.debug('Generating new pub/priv key pair') self.dh = ec.generate_private_key(SECP521R1(), default_backend()) self.peer_public_key = self.pubkey_from_xml(xml) logging.debug('Imported peer public key') self.shared_key = self.dh.exchange(ec.ECDH(), self.peer_public_key) sha256 = hashes.Hash(hashes.SHA256(), backend=default_backend()) sha256.update(self.shared_key) self.derived_key = sha256.finalize()
def get_ec2_curve(crv_id: COSECRV) -> EllipticCurve: """Turn an EC2 COSE crv identifier into a corresponding curve""" if crv_id == COSECRV.P256: return SECP256R1() elif crv_id == COSECRV.P384: return SECP384R1() elif crv_id == COSECRV.P521: return SECP521R1() raise UnsupportedEC2Curve(f"Unrecognized EC2 curve {crv_id}")
def cryptography_ec2_public_key( credential_public_key: EC2CredentialPublicKey) -> PublicKey: x = int.from_bytes(credential_public_key.x, 'big') y = int.from_bytes(credential_public_key.y, 'big') curve = None if credential_public_key.crv.name == 'P_256': curve = SECP256R1() elif credential_public_key.crv.name == 'P_384': curve = SECP384R1() elif credential_public_key.crv.name == 'P_521': curve = SECP521R1() else: raise UnimplementedError( 'Unsupported cryptography EC2 curve {}'.format( credential_public_key.crv.name)) ecpn = EllipticCurvePublicNumbers(x, y, curve) return ecpn.public_key(default_backend())
def generate_secpr1_keys(secrp1_type): # TODO fix raise Exception( "secpXXXr1 has some bugs, the received application data can't be encrypted" ) if secrp1_type == "secp256r1": curve = SECP256R1() coordinate_byte_size = 32 elif secrp1_type == "secp384r1": curve = SECP384R1() coordinate_byte_size = 48 elif secrp1_type == "secp521r1": curve = SECP521R1() coordinate_byte_size = 66 else: raise Exception("Unknown secpr1 type {}".format(secrp1_type)) private_key = generate_private_key(curve, default_backend()) private_key_bytes = private_key.private_bytes( encoding=Encoding.DER, format=PrivateFormat.PKCS8, encryption_algorithm=NoEncryption(), ) public_key = private_key.public_key() public_key_bytes = public_key.public_bytes( encoding=Encoding.DER, format=PublicFormat.SubjectPublicKeyInfo) # The key must be shared in a specific format so we generate this for this curve # https://tlswg.org/tls13-spec/antoine_address/draft-ietf-tls-tls13.html#ecdhe-param # For secp256r1, secp384r1, and secp521r1, the contents are the serialized value of the following struct: # struct { # uint8 legacy_form = 4; # opaque X[coordinate_length]; # opaque Y[coordinate_length]; # } UncompressedPointRepresentation; x = private_key.private_numbers().public_numbers.x y = private_key.private_numbers().public_numbers.y shared_key = ( b"\x04" + x.to_bytes(coordinate_byte_size, Crypto_Helper.ENDINESS) + y.to_bytes(coordinate_byte_size, Crypto_Helper.ENDINESS)) return private_key_bytes, public_key_bytes, shared_key
def _ecdh(cls, curve: 'CoseCurve', private_key: 'EC2', public_key: 'EC2') -> bytes: if curve == curves.P256(): curve_instance = SECP256R1() elif curve == curves.P384(): curve_instance = SECP384R1() elif curve == curves.P521(): curve_instance = SECP521R1() else: raise CoseIllegalCurve() d_value = int(hexlify(private_key.d), 16) x_value = int(hexlify(public_key.x), 16) y_value = int(hexlify(public_key.y), 16) d = ec.derive_private_key(d_value, curve_instance, default_backend()) p = ec.EllipticCurvePublicNumbers(x_value, y_value, curve_instance) p = p.public_key(default_backend()) shared_key = d.exchange(ECDH(), p) return shared_key
def generate_key(crv: Union[Type['CoseCurve'], str, int], optional_params: dict = None) -> 'EC2Key': """ Generate a random EC2Key COSE key object. :param crv: Specify an :class:`~cose.attributes.algorithms.CoseEllipticCurves`. :param optional_params: Optional key attributes for the :class:`~cose.keys.ec2.EC2Key` object, e.g., \ :class:`~cose.keys.keyparam.KpAlg` or :class:`~cose.keys.keyparam.KpKid`. :return: An COSE `EC2Key` key. """ if type(crv) == str or type(crv) == int: crv = CoseCurve.from_id(crv) if crv == P256: curve_obj = SECP256R1() elif crv == P384: curve_obj = SECP384R1() elif crv == P521: curve_obj = SECP521R1() else: raise CoseIllegalCurve(f'Illegal COSE curve: {crv}') private_key = ec.generate_private_key(curve_obj, backend=default_backend()) d_value = private_key.private_numbers().private_value x_coor = private_key.public_key().public_numbers().x y_coor = private_key.public_key().public_numbers().y return EC2Key(crv=crv, d=d_value.to_bytes((d_value.bit_length() + 7) // 8, byteorder="big"), x=x_coor.to_bytes((x_coor.bit_length() + 7) // 8, byteorder="big"), y=y_coor.to_bytes((y_coor.bit_length() + 7) // 8, byteorder="big"), optional_params=optional_params)
def cryptography_ec2_public_key( credential_public_key: EC2CredentialPublicKey) -> EC2PublicKey: """Convert an `EC2CredentialPublicKey` into a cryptography `EC2PublicKey`. Args: credential_public_key (EC2CredentialPublicKey): The key to convert. Returns: A cryptography `EC2PublicKey`. Raises: UnimplementedError: If the conversion logic for the given type of CredentialPublicKey has not been implemented. PublicKeyConversionError: If the provided key could not be converted into a valid cryptography `EC2PublicKey`. """ x = int.from_bytes(credential_public_key.x, 'big') y = int.from_bytes(credential_public_key.y, 'big') curve: Optional[Union[SECP256R1, SECP384R1, SECP521R1]] = None if credential_public_key.crv.name == 'P_256': curve = SECP256R1() elif credential_public_key.crv.name == 'P_384': curve = SECP384R1() elif credential_public_key.crv.name == 'P_521': curve = SECP521R1() else: raise UnimplementedError( 'Unsupported cryptography EC2 curve {}'.format( credential_public_key.crv.name)) assert curve is not None ecpn = EllipticCurvePublicNumbers(x, y, curve) try: return ecpn.public_key(default_backend()) except ValueError: raise PublicKeyConversionError('Invalid EC2 public key')
def generate_private_key(self): logging.debug('Generating new pub/priv key pair') self.dh = ec.generate_private_key(SECP521R1(), default_backend())
def __init__(self, psk): self.psk = unhexlify(psk) self.dh = ec.generate_private_key(SECP521R1(), default_backend()) self.derived_key = None