EC2 Key

Overview

COSE EC2 keys can be used for signing and verifying pycose.messages.sign1message.Sign1Message and pycose.messages.signmessage.SignMessage COSE messages, and also for key agreement in KeyAgreementWithKeyWrap and DirectKeyAgreement COSE recipient structures.

COSE EC2 keys can be created using the EC2Key class or from a standard Python dictionary. The following two examples shows how to create COSE EC2 keys using both methods. The keys are serialized and subsequently deserialized.

>>> import os
>>> from binascii import unhexlify
>>> from pycose.keys import EC2Key, CoseKey

>>> # get 32 random bytes as private key (potentially not a valid key for curve P_256)
>>> private_key = unhexlify(b'57c92077664146e876760c9520d054aa93c3afb04e306705db6090308507b4d3')
>>> cose_key = EC2Key(crv='P_256', d=private_key, optional_params={'ALG': 'ES256'})

>>> #encode/serialize key
>>> serialized_key = cose_key.encode()
>>> serialized_key
b'\xa6\x01\x02\x03& \x01!X \xba\xc5\xb1\x1c\xad\x8f\x99\xf9\xc7+\x05\xcfK\x9e&\xd2D\xdc\x18\x9ftR(%Z!\x9a\x86\xd6\xa0\x9e\xff"X  \x13\x8b\xf8-\xc1\xb6\xd5b\xbe\x0f\xa5J\xb7\x80J:d\xb6\xd7,\xcf\xedko\xb6\xed(\xbb\xfc\x11~#X W\xc9 wfAF\xe8vv\x0c\x95 \xd0T\xaa\x93\xc3\xaf\xb0N0g\x05\xdb`\x900\x85\x07\xb4\xd3'
>>> # deserialize key
>>> CoseKey.decode(serialized_key)
<COSE_Key(EC2Key): {'EC2KpD': "b'W\\xc9 wf' ... (32 B)", 'EC2KpY': "b' \\x13\\x8b\\xf8-' ... (32 B)", 'EC2KpX': "b'\\xba\\xc5\\xb1\\x1c\\xad' ... (32 B)", 'EC2KpCurve': 'P256', 'KpKty': 'KtyEC2', 'KpAlg': 'Es256'}>
>>> from binascii import unhexlify
>>> from pycose.keys import EC2Key, CoseKey

>>> # create key object from a dict, both the key type and key bytes (KTY and K) are mandatory attributes.
>>> key_attribute_dict = {
...     'KTY': 'EC2',
...     'CURVE': 'P_256',
...     'ALG': 'ES256',
...     'D': unhexlify(b'57c92077664146e876760c9520d054aa93c3afb04e306705db6090308507b4d3')}

>>> cose_key = CoseKey.from_dict(key_attribute_dict)

>>> #encode/serialize key
>>> serialized_key = cose_key.encode()
>>> serialized_key
b'\xa6\x01\x02\x03& \x01!X \xba\xc5\xb1\x1c\xad\x8f\x99\xf9\xc7+\x05\xcfK\x9e&\xd2D\xdc\x18\x9ftR(%Z!\x9a\x86\xd6\xa0\x9e\xff"X  \x13\x8b\xf8-\xc1\xb6\xd5b\xbe\x0f\xa5J\xb7\x80J:d\xb6\xd7,\xcf\xedko\xb6\xed(\xbb\xfc\x11~#X W\xc9 wfAF\xe8vv\x0c\x95 \xd0T\xaa\x93\xc3\xaf\xb0N0g\x05\xdb`\x900\x85\x07\xb4\xd3'

>>> # deserialize key
>>> CoseKey.decode(serialized_key)
<COSE_Key(EC2Key): {'EC2KpD': "b'W\\xc9 wf' ... (32 B)", 'EC2KpY': "b' \\x13\\x8b\\xf8-' ... (32 B)", 'EC2KpX': "b'\\xba\\xc5\\xb1\\x1c\\xad' ... (32 B)", 'EC2KpCurve': 'P256', 'KpKty': 'KtyEC2', 'KpAlg': 'Es256'}>

Alternatively you can use the generate_key() method. It generates a random COSE EC2 Key for a given curve. Valid curves are P256, P384, and P521.

>>> from pycose.keys import EC2Key

>>> # generate a random key
>>> cose_key = EC2Key.generate_key(crv='P_521')

When creating a COSE EC2 Key from a dictionary, you have to make sure that the dictionary holds the KpKty, EC2KpCurve, and either EC2KpD (for private COSE EC2 keys) or EC2KpX and EC2KpY (for public COSE EC2 keys) key attributes. These attributes are mandatory for a valid COSE EC2 Key. If you don’t specify them, the from_dict() will throw an exception.

>>> from pycose.keys import EC2Key, CoseKey

>>> key_attribute_dict = {
...     'KTY': 'EC2',
...     'CURVE': 'P_384'}

>>> CoseKey.from_dict(key_attribute_dict)
Traceback (most recent call last):
  File "/usr/lib/python3.6/doctest.py", line 1330, in __run
    compileflags, 1), test.globs)
  File "<doctest default[2]>", line 1, in <module>
    CoseKey.from_dict(key_attribute_dict)
  File "/home/timothy/Projects/pycose/pycose/keys/pycosekey.py", line 69, in from_dict
    key_obj = cls._key_types[received[KpKty.fullname]].from_dict(received)
  File "/home/timothy/Projects/pycose/pycose/keys/ec2.py", line 63, in from_dict
    return cls(crv=curve, x=x, y=y, d=d, optional_params=cose_key)
  File "/home/timothy/Projects/pycose/pycose/keys/ec2.py", line 74, in __init__
    raise CoseInvalidKey("Either the public values or the private value must be specified")
pycose.exceptions.CoseInvalidKey: Either the public values or the private value must be specified

The key attributes of the COSE EC2 Key can be represented by their string label, the integer identifier or the corresponding python class.

>>> from binascii import unhexlify
>>> from pycose.keys import EC2Key, CoseKey
>>> from pycose.keys.keytype import KtyEC2
>>> from pycose.algorithms import Es256
>>> from pycose.keys.curves import P256
>>> from pycose.keys.keyparam import KpKty, KpAlg, EC2KpD, EC2KpCurve

>>> # key attribute dict using string representations
>>> key_attribute_dict1 = {
...     'KTY': 'EC2',
...     'CURVE': 'P_256',
...     'ALG': 'ES256',
...     'D': unhexlify(b'57c92077664146e876760c9520d054aa93c3afb04e306705db6090308507b4d3')}

>>> cose_key1 = CoseKey.from_dict(key_attribute_dict1)

>>> # key attribute dict using integer identifiers
>>> key_attribute_dict2 = {
...     1: 2,
...     -1: 1,
...     3: -7,
...     -4: unhexlify(b'57c92077664146e876760c9520d054aa93c3afb04e306705db6090308507b4d3')}

>>> cose_key2 = CoseKey.from_dict(key_attribute_dict2)

>>> # key attribute dict using Python classes
>>> key_attribute_dict3 = {
...     KpKty: KtyEC2,
...     EC2KpCurve: P256,
...     KpAlg: Es256,
...     EC2KpD: unhexlify(b'57c92077664146e876760c9520d054aa93c3afb04e306705db6090308507b4d3')}

>>> cose_key3 = CoseKey.from_dict(key_attribute_dict3)

>>> # key attribute dict using a mix of attribute representations
>>> key_attribute_dict4 = {
...     1: 'EC2',
...     EC2KpCurve: 1,
...     'ALG': Es256,
...     EC2KpD: unhexlify(b'57c92077664146e876760c9520d054aa93c3afb04e306705db6090308507b4d3')}

>>> cose_key4 = CoseKey.from_dict(key_attribute_dict4)

>>> # all COSE Symmetric key objects are equal
>>> cose_key1 == cose_key2 == cose_key3 == cose_key4
True

API

class pycose.keys.ec2.EC2Key(crv, x=b'', y=b'', d=b'', optional_params=None, allow_unknown_key_attrs=True)

Initialize a COSE key from its components

Not passing a y component is accepted; in this case, one (of the two) valid y will be found for the x. This is good enough for everything that only operates on the x of any derived outputs (in “compact” mode), as per RFC 6090 Section 4.2.

classmethod from_dict(cose_key)

Returns an initialized COSE Key object of type EC2Key.

Parameters:

cose_key – Dict containing COSE Key parameters and their values.

Returns:

an initialized EC2Key key

property crv

Returns the mandatory EC2KpCurve attribute of the COSE EC2 Key object.

property x

Returns the mandatory EC2KpX attribute of the COSE EC2 Key object.

property alg

Returns the value of the KpAlg key parameter

static base64decode(to_decode)

Decodes BASE64 encoded keys to bytes.

Parameters:

to_decode – BASE64 encoded key.

Returns:

Key as bytes.

static base64encode(to_encode)

Encodes key bytes as a string.

Parameters:

to_encode – Bytes to encode.

Returns:

BASE64 encoding.

property base_iv

Returns the value of the KpBaseIV key parameter

encode()

Encodes the COSE key as a CBOR map

Returns:

A COSE key encoded as CBOR map

static from_pem_private_key(pem, password=None, optional_params=None)

Initialize a COSE key from a PEM-encoded private key.

Parameters:
  • pem – PEM-encoded private key.

  • password – Password to decrypt the key.

  • optional_params – Optional parameters to add to the key.

Returns:

an initialized CoseKey object.

static from_pem_public_key(pem, optional_params=None)

Initialize a COSE key from a PEM-encoded public key.

Parameters:
  • pem – PEM-encoded public key.

  • optional_params – Optional parameters to add to the key.

Returns:

an initialized CoseKey object.

property kid

Returns the value of the KpKid key parameter

property kty

Returns the value of the mandatory KpKty key parameter

property y

Returns the mandatory EC2KpY attribute of the COSE EC2 Key object.

property d

Returns the mandatory EC2KpD attribute of the COSE EC2 Key object.

property key_ops

Returns the value of the KpKeyOps key parameter

classmethod generate_key(crv, optional_params=None)

Generate a random EC2Key COSE key object.

Parameters:
  • crv – Specify an CoseEllipticCurves.

  • optional_params – Optional key attributes for the EC2Key object, e.g., KpAlg or KpKid.

Returns:

An COSE EC2Key key.