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