Concise Binary Object Representation (CBOR) [1] integrates security into small data objects and small message sizes. COSE (CBOR Object Signing and Encryption) [2] can then build on this to include signatures, message authentication codes (MACs) and encryption and creating serialised objects. In this case we will use a symmetric key to encrypt a message, and then decrypt it. In this case we will use AES GCM using a random 256-bit key (32 bytes):
COSE and CBOR - 256-bit AES Symmetric Key |
Outline
In computer security, we often have to represent binary data, in single values or groups of characters, bytes, words, long words, signed integers, floating-point values, double-precision floating-point values, and so on. This might be in the form of a data object, a signature or even encrypted content. For this, the ANS.1 DER format is often used, such as presenting digital certificates and signatures. An improvement on this for small messages with security is Concise Binary Object Representation (CBOR) — and which is defined in RFC8949 [1]. While JSON represents text-based data objects CBOR focuses on binary objects. It has been designed to create a lightweight encoder and decoder. This supports the use of CBOR within an IoT infrastructure. The data, also, does not require a data schema to be able to decode it, along with being extensible.
CBOR integrates security into small data objects and small message sizes. This includes signatures, message authentication codes (MACs), encryption and creating serialised objects. In this case, we will use a symmetric key to encrypt a message and then decrypt it. In this case we will use AES GCM with a dynamic 256-bit encryption key:
from binascii import unhexlify,hexlify from cose.messages import Enc0Message,CoseMessage from cose.keys import SymmetricKey from os import urandom import sys mymsg="hello" if (len(sys.argv)>1): mymsg=str(sys.argv[1]) IV = urandom(16) msg = Enc0Message( phdr={'ALG': 'A256GCM', 'IV': IV}, uhdr={'KID': b'test@home'}, payload=mymsg.encode() ) priv = urandom(32) cose_key = SymmetricKey(k=priv) msg.key = cose_key msg.encode() cose_msg = CoseMessage.decode(msg.encode()) cose_msg.key = cose_key rtn=cose_msg.decrypt() print ("Input message: ",mymsg) print ("\nPrivate key: ",hexlify(priv).decode()) print ("\nIV: ",hexlify(IV).decode()) print ("\nCOSE key: ",cose_msg.key) print ("COSE message: ",msg) print ("COSE encoded: ",hexlify(cose_msg.payload)) print ("\nDecrypted: ",rtn.decode())
The IV value applied in this case is random 16 byte value (128 bits). A sample run shows the format of the key and message, and where we can encode the encrypted data object into a hex stream:
Input message: hello Private key: b68b6db736f1c7964358832fe85d4bc4b119a347ef49e4b730b6509cb774802f IV: bfa0380756a1a95a840e82e9af8c324b COSE key: <COSE_Key(Symmetric): {'SymKpK': "b'\\xb6\\x8bm\\xb76' ... (32 B)" , 'KpKty' : 'KtySymmetric' }> COSE message: <COSE_Encrypt0: [{'Algorithm': 'A256GCM' , 'IV' : "b'\\xbf\\xa08\\x07V' ... (16 B)" }, {'KID': b'test@home'}, b'hello' ... (5 B)]> COSE encoded: b'a862807515d22d960308e9dec5609b83280c244dd2' Decrypted: hello
Coding
To run the code, you need to pip install cose:
References
[1] Bormann, C., & Hoffman, P. (2020). RFC 8949 Concise Binary Object Representation (CBOR). [here].
[2] Schaad, J. (2017), RFC 8152 – CBOR Object Signing and Encryption (COSE), 2017. [here]