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 create a CWT token [3], and sign with an HMAC signature.
COSE and CBOR - CWT Tokens |
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.
Most of what we process is untrusted, and cannot really be traced for its correctness. If we started the Internet now, we would probably encapsulate our data, and integrate integrity checks, and digitally sign for correctness. For the rights to any data and servers, we would show digitally signed claims to things, and that we can gain and then pass to a verifier to give us rights. Basically, too, we would live in a zero trust world, and where we had no rights to anything, unless we had a signed claim on something. This claim could last for an hour or for years, but would be limited in some way.
And so we should be moving into a world of tokens and claims. You probably already do this when you are logging into a system, and where you get a token that you can pass to all the systems you connect to in your corporate network. The claim is that you have the rights to log into the system and with given rights of access. This claim will time out after a while and you must reclaim your rights. But we can extend this to any data, and where we can sign for the data from a trusted entity. This can be with a secret key (such as with HMAC) or through public-key encryption (and where the token is signed with the private key of the trusted entity, and then proven with the public key).
Most of the tokens are in plain sight and where we can see the data contained. One way to overcome this is to encrypt the token, and where only trusted entities can decrypt it. Let’s say that we capture data from a nuclear power plant, and want to sign the data from a trusted sensor that captured it. In this way, we can prove the data provenance. But, we do not want Eve to capture the token and gain an advantage from the discovery of data in the token. One way we can do this is with a CWT — CBOR Web Token [here]. This supports a binary encapsulation for the token and also encryption. This method works well for a range of systems, including IoT devices, and builds on the JSON Web token format (but adds in encryption and is light-weight).
With this, the token has certain fields, including “iss” — the issuer, “sub” — the subject, “cti” — the claim that is made (eg that the user has rights to access the system) and “exp” — the expiry date. If the date of issue is in the past, the token should not be trusted, and the user is prompted to reclaim their rights. A sample run gives [here]:
Message: hello Key: b'f852f0731b0f3890fa0e82bb4de02ca354d4d1040387f7c77d5f518f700fc098' Token (hex): b'\xd1\x84C\xa1\x01\x05\xa1\x04DmyidXH\xa6\x01rcoaps://an.example\x02pMy Asecuritysite\x07MNetwork Login\x04\x1a\x91\xadx\xb0\x05\x1aa8\\\xb9\x06\x1aa8\\\xb9X \xd5\xbbk\x05"R\xf3\x02D\x9c\x8a\xcf*I1Q\xc8tD@w\xabcb}\x10\x8c\x97& \xb9\xcc' Token: b'd18443a10105a104446d7969645848a60172636f6170733a2f2f616e2e6578616d706c6502704d792041736563757269747973697465074d4e6574776f726b204c6f67696e041a91ad78b0051a61385cb9061a61385cb95820d5bb6b052252f302449c8acf2a493151c874444077ab63627d108c972620b9cc' Token (decoded): {1: 'coaps://an.example', 2: 'My Asecuritysite', 7: b'Network Login', 4: 2444064944, 5: 1631083705, 6: 1631083705}
An overview of this process is given below. In this case, Alice requests for a service from the issuer, and who then create a signed token, and which is passed to the service (Bob) and who checks the HMAC signature on the token:
from cwt import COSE, COSEKey from binascii import unhexlify,hexlify import cwt import sys from os import urandom mymsg='hello' method='HS256' subject="My Asecuritysite" claim="Network Login" if (len(sys.argv)>1): subject=str(sys.argv[1]) if (len(sys.argv)>2): claim=str(sys.argv[2]) key=urandom(32) ctx = COSE.new(alg_auto_inclusion=True, kid_auto_inclusion=True) mac_key = COSEKey.from_symmetric_key(key=key,alg=method, kid="myid") token = cwt.encode({"iss": "coaps://an.example", "sub": subject, "cti": claim, "exp":2444064944}, mac_key) print("Message: ",mymsg) print ("Key: ",hexlify(key)) print ("Token (hex): ",token) print ("Token: ",hexlify(token)) res=cwt.decode(token,mac_key) print ("\nToken (decoded): ",res)
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]
[3] Jones, M., Wahlstroem, E., Erdtman, S., & Tschofenig, H. (2018). Cbor web token (cwt). RFC 8392, Standards Track, IETF. [here]