RFC 9338
CBOR Object Signing and Encryption (COSE): Countersignatures
RFC 9338: CBOR Object Signing and Encryption (COSE): Countersignatures π
Okay bestie, let's start with the basics π This one comes from the Internet Engineering Task Force (IETF) and was written by J. Schaad of August Cellars. It was published in December 2022 as a Standards Track document, and it's also STD 96 π The ISSN is 2070-1721. It updates RFC 9052, and the title block doesn't list anything it obsoletes.
Abstract πΈ
Concise Binary Object Representation (CBOR) is a data format designed for small code size and small message size. CBOR Object Signing and Encryption (COSE) defines a set of security services for CBOR. This document defines a countersignature algorithm along with the needed header parameters and CBOR tags for COSE. This document updates RFC 9052.
Status of This Memo π¦
This is an Internet Standards Track document.
This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 7841.
Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at https://www.rfc-editor.org/info/rfc9338.
Copyright Notice π₯
Copyright (c) 2022 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.
Table of Contents π§
1. Introduction
1.1. Requirements Terminology
1.2. CBOR Grammar
1.3. Document Terminology
2. Countersignature Header Parameters
3. Version 2 Countersignatures
3.1. Full Countersignatures
3.2. Abbreviated Countersignatures
3.3. Signing and Verification Process
4. CBOR Encoding Restrictions
5. IANA Considerations
5.1. CBOR Tags Registry
5.2. COSE Header Parameters Registry
6. Security Considerations
7. References
7.1. Normative References
7.2. Informative References
Appendix A. Examples
A.1. Examples of Signed Messages
A.1.1. Countersignature
A.2. Examples of Signed1 Messages
A.2.1. Countersignature
A.3. Examples of Enveloped Messages
A.3.1. Countersignature on Encrypted Content
A.4. Examples of Encrypted Messages
A.4.1. Countersignature on Encrypted Content
A.5. Examples of MACed Messages
A.5.1. Countersignature on MAC Content
A.6. Examples of MAC0 Messages
A.6.1. Countersignature on MAC0 Content
Acknowledgments
Author's Address
1. Introduction β¨
Okay so there's been a huge focus on small, constrained devices that make up the Internet of Things (IoT) π§Έ One of the standards that came out of that work is "Concise Binary Object Representation (CBOR)" [RFC8949]. CBOR stretched the data model of the JavaScript Object Notation (JSON) [STD90] by allowing binary data, among other changes. Several IETF working groups dealing with the IoT world have adopted CBOR as their way of encoding data structures. CBOR was designed to be small in both messages transported and implementation size, and to have a schema-free decoder. There's a need for message security services in IoT, so using CBOR as the message-encoding format is a very natural fit π
A countersignature is a second signature that confirms the primary signature. While CBOR Object Signing and Encryption (COSE) was moving toward Internet Standard, people noticed that the description of countersignature security properties was incorrect for the COSE_Sign1 structure mentioned in Section 4.5 of [RFC8152]. To fix this, the COSE Working Group decided to remove all of the countersignature text from [RFC9052], which obsoletes [RFC8152]. This document defines a new countersignature with the desired security properties π₯
The problem with the previous countersignature algorithm was that the cryptographically computed value wasn't always included. The assumption that the cryptographic value was in the third slot of the array was known not to be true at the time, but for the Message Authentication Code (MAC) structures this wasn't considered a problem. The new algorithm defined in this document requires more values to be included in the countersignature computation. The exception is the COSE_Signature structure, which has no cryptographically computed value π
The new algorithm is designed to produce the same countersignature value in the cases where the computed cryptographic value was already included. So for those structures, all that needs to be done is change the value of the header parameter π
With this document published, implementers are encouraged to migrate uses of the previous countersignature algorithm to the one specified here. Specifically, uses of "CounterSignature" will migrate to "CounterSignatureV2", and uses of "CounterSignature0" will migrate to "CounterSignature0V2". Also, verification of "CounterSignature" must be supported by new implementations to stay compatible with senders that adhere to [RFC8152], which assumes that all implementations will understand "CounterSignature" as header parameter label 7. Likewise, verification of "CounterSignature0" may be supported for further compatibility π¦
1.1. Requirements Terminology π
Okay, here's the official word list. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
1.2. CBOR Grammar π§
The CBOR grammar in this document uses the Concise Data Definition Language (CDDL) [RFC8610].
You can pull the collected CDDL out of the XML version of this document with the XPath expression below. (Depending on the XPath evaluator you're using, you might need to deal with > as an entity.)
//sourcecode[@type='cddl']/text()
CDDL expects the initial non-terminal symbol to be the first symbol in the file. That's why the first fragment of CDDL is shown here π
start = COSE_Countersignature_Tagged / Internal_Types
; This is defined to make the tool quieter:
Internal_Types = Countersign_structure / COSE_Countersignature0
The non-terminal Internal_Types is there for the automated validation tools used while writing this document. It references the non-terminals that are used for security computations but aren't emitted for transport π«Ά
1.3. Document Terminology π
In this document, we use the following terminology.
"Byte" is a synonym for "octet".
The Constrained Application Protocol (CoAP) is a specialized web transfer protocol for use in constrained systems. It is defined in [RFC7252].
"Context" is used throughout this document to represent information that is not part of the COSE message. Context can come from different sources, including protocol interactions, associated key structures, and application configuration. The context to use can be implicit, identified using either the "kid context" header parameter defined in [RFC8613] or a protocol-specific identifier. Context should generally be included in the cryptographic construction; for more details, see Section 4.4 of [RFC9052] π
The term "byte string" is used for sequences of bytes, while the term "text string" is used for sequences of characters.
2. Countersignature Header Parameters π
This section defines a set of common header parameters. A summary can be found in Table 1. This table should be consulted to determine the value of the label and the type of the value.
The set of header parameters defined in this section is:
- V2 countersignature: This header parameter holds one or more countersignature values. Countersignatures provide a method of having a second party sign some data. The countersignature header parameter can occur as an unprotected attribute in any of the following structures defined in [RFC9052]: COSE_Sign1, COSE_Signature, COSE_Encrypt, COSE_recipient, COSE_Encrypt0, COSE_Mac, and COSE_Mac0. Details of version 2 countersignatures are found in Section 3.
+=================+=====+==========================+================+
|Name |Label| Value Type |Description |
+=================+=====+==========================+================+
|Countersignature |11 | COSE_Countersignature / |V2 |
|version 2 | | [+ COSE_Countersignature |countersignature|
| | | ] |attribute |
+-----------------+-----+--------------------------+----------------+
|Countersignature0|12 | COSE_Countersignature0 |V2 Abbreviated |
|version 2 | | |Countersignature|
+-----------------+-----+--------------------------+----------------+
Table 1: Common Header Parameters
The CDDL fragment that represents the set of header parameters defined in this section is below. Each header parameter is tagged as optional because it doesn't need to be in every map. The header parameters required in specific maps are discussed above β¨
CountersignatureV2_header = (
? 11 => COSE_Countersignature / [+ COSE_Countersignature]
)
Countersignature0V2_header = (
? 12 => COSE_Countersignature0
)
3. Version 2 Countersignatures β¨
Okay bestie, so a countersignature is normally a second signature that confirms a primary signature ποΈ. The classic example is a notary public stamping a document to say "yep, I watched them sign this" π . Notaries usually add a timestamp for when it happened, but COSE doesn't have a timestamp defined yet π₯Ί. A future document might define one and stick it in as a protected header parameter β°. So putting a countersignature on either a COSE_Signature or a COSE_Sign1 object is literally the traditional definition, no cap π. This doc stretches the idea so countersignatures can go on all of the security structures β¨. And the countersignature is its own separate operation from the original one, even when the same user does both, like what [GROUP-OSCORE] does π«Ά.
COSE gives you two flavours of countersignature π. Full countersignatures use the COSE_Countersignature structure, which is shaped exactly like COSE_Signature. So full ones can have protected and unprotected attributes, and they can even be chained π. Abbreviated countersignatures use COSE_Countersignature0, which holds only the signature value and nothing else π¦. You can't convert between the two, because the signature computation includes a parameter that says which structure is in use. If you convert one, it will fail signature validation π.
The version 2 countersignature changes how the signature gets computed compared to the original version from Section 4.5 of [RFC8152] π₯. The new version includes the cryptographic material generated for all of the structures, not just a subset of them π.
COSE was designed to be uniform in how its data structures are specified, and that's iconic because it means countersignatures can expand way beyond signing a signature π. You can sign most of the structures without making a whole new signing layer β¨. But you have to be clear about the security properties you end up with π§. On a COSE_Signature or COSE_Sign1, the normal countersignature meaning holds up: it makes a statement that the signature exists and, once a timestamp is defined, when it existed β°. On a COSE_Mac or COSE_Mac0, the payload gets included along with the MAC value π. On a COSE_Encrypt or COSE_Encrypt0, you're attesting that the encrypted data exists π. Here's the tea: attesting to the encrypted data is NOT the same as attesting to the unencrypted data π. If you want the second one, you need to sign the data first and then encrypt it π . It's also always possible to build cases where two different keys both decrypt successfully, the tag check passes, and you get two completely different plaintexts π±. A countersignature on the encrypted data can't detect that situation π.
3.1. Full Countersignatures
The COSE_Countersignature structure gives you the same set of capabilities as a COSE_Signature, so everything a signature can do, this structure can do too π. The countersigner doesn't need any relationship with whoever produced the thing being countersigned, because key and algorithm identification can live in the countersignature attributes π§. And yes, the countersignature can itself be countersigned πΈ. That's a feature protocols like long-term archiving services actually need π. You can read more about how countersignatures get used in the evidence record syntax described in [RFC4998] π.
A full countersignature can be encoded as tagged or untagged, depending on what you're doing β¨. A tagged COSE_Countersignature is identified by CBOR tag 19 π·οΈ. It's the same structure used for a signer on a signed object, so no surprises there π
. The CDDL fragment for full countersignatures is:
COSE_Countersignature_Tagged = #6.19(COSE_Countersignature)
COSE_Countersignature = COSE_Signature
For the field details, check Section 4.1 of [RFC9052] π. There's an example of a countersignature on a signature in Appendix A.1.1 π. And an example of a countersignature inside an encryption object is in Appendix A.3.1 π¦.
Also, only a signature algorithm with appendix (see Section 8.1 of [RFC9052]) can be used for countersignatures π«. The reason is that the body has to be processable without evaluating the countersignature, and signature schemes with message recovery can't do that π€.
3.2. Abbreviated Countersignatures
Abbreviated countersignatures are for encrypted group messaging, where you need to know who the message came from but you want the countersignature to be as tiny as possible π€. For these, there's no provision for any protected attributes tied to the signing operation π ββοΈ. Instead, the parameters for computing or verifying the abbreviated countersignature come from the same context that describes the encryption, signature, or MAC processing π§©.
The CDDL fragment for abbreviated countersignatures is:
COSE_Countersignature0 = bstr
The byte string holding the signature value goes into the Countersignature0 attribute π. That attribute then gets encoded as an unprotected header parameter π«Ά.
3.3. Signing and Verification Process
To make a signature, you need a well-defined byte string first, and that's where Countersign_structure comes in πͺ. It's used to build the canonical form. The signing and verification process takes in the countersignature target structure (COSE_Signature, COSE_Sign1, COSE_Sign, COSE_Mac, COSE_Mac0, COSE_Encrypt, or COSE_Encrypt0), the signer information (COSE_Signature), and the application data (external source) π°. A Countersign_structure is a CBOR array π¦. Before you compute the signature, the target structure needs all of its cryptographic functions finalized π. The fields of Countersign_structure, in order, are:
context: A context text string identifying the context of the signature. It's one of the following:"CounterSignature"for countersignatures using theCOSE_Countersignaturestructure whenother_fieldsis absent."CounterSignature0"for countersignatures using theCOSE_Countersignature0structure whenother_fieldsis absent."CounterSignatureV2"for countersignatures using theCOSE_Countersignaturestructure whenother_fieldsis present."CounterSignature0V2"for countersignatures using theCOSE_Countersignature0structure whenother_fieldsis present.
body_protected: The serialized protected attributes from the target structure, encoded as a bstr. If there are no protected attributes, a zero-length byte string is used.sign_protected: The serialized protected attributes from the signer structure, encoded as a bstr. If there are no protected attributes, a zero-length byte string is used. This field is omitted for theCountersignature0V2attribute.external_aad: The externally supplied additional authenticated data (AAD) from the application, encoded as a bstr. If it isn't supplied, it defaults to a zero-length byte string. (See Section 4.4 of [RFC9052] for application guidance on building this field.)payload: The payload to be signed, encoded as a bstr. The payload goes here no matter how it gets transported π¨.other_fields: Left out if the target structure only has two bstr fields. Otherwise, this is an array of all the bstr fields after the second one. For example, for the COSE_Sign1 structure this is an array of one element containing the signature value π§Ύ.
The CDDL fragment that describes all of that is:
Countersign_structure = [
context : "CounterSignature" / "CounterSignature0" /
"CounterSignatureV2" / "CounterSignature0V2" /,
body_protected : empty_or_serialized_map,
? sign_protected : empty_or_serialized_map,
external_aad : bstr,
payload : bstr,
? other_fields : [+ bstr ]
]
How to compute a countersignature, step by step π :
- Create a
Countersign_structureand fill in the appropriate fields. - Create the value ToBeSigned by encoding the
Countersign_structureto a byte string, using the encoding described in Section 4. - Call the signature creation algorithm, passing in K (the key to sign with), alg (the algorithm to sign with), and ToBeSigned (the value to sign).
- Put the resulting signature value in the right spot. For full countersignatures, that's the "signature" field of the
COSE_Countersignaturestructure (see Section 3.1). For abbreviated countersignatures, it's the value of theCountersignature0attribute (see Section 3.2).
The steps for verifying a countersignature π:
- Create a
Countersign_structureand fill in the appropriate fields. - Create the value ToBeSigned by encoding the
Countersign_structureto a byte string, using the encoding described in Section 4. - Call the signature verification algorithm, passing in K (the key to verify with), alg (the algorithm used to sign with), ToBeSigned (the value to sign), and sig (the signature to be verified).
Signature verification isn't the whole story, though π. The application also has to check that the key is correctly paired with the signing identity, and that the signing identity is authorized before it does anything π‘οΈ.
4. CBOR Encoding Restrictions π§
The deterministic encoding rules are defined in Section 4.2 of [RFC8949] π. They get narrowed down further in Section 9 of [RFC9052] βοΈ. The narrowed deterministic encoding rules MUST be used so that every implementation generates the same byte string for the "to be signed" value π―.
5. IANA Considerations π
The registries and registrations listed below were created while [RFC8152] was being processed ποΈ. Most of the actions are just updating the references so they point to this document π.
5.1. CBOR Tags Registry
IANA created a registry titled "CBOR Tags" as part of processing RFC 7049, and that registry was later replaced by [RFC8949] π·οΈ.
IANA has assigned a new tag for the CounterSignature type in the "CBOR Tags" registry π:
Tag: 19
Data Item: COSE_Countersignature
Semantics: COSE standalone V2 countersignature
Reference: RFC 9338
5.2. COSE Header Parameters Registry β¨
okay so IANA made a registry called "COSE Header Parameters" while processing [RFC8152] π and it's giving organized.
IANA registered Countersignature version 2 (label 11) and Countersignature0 version 2 (label 12) in that registry π. For these entries the "Value Type" and "Description" are in Table 1, the "Value Registry" is blank, and the "Reference" is "RFC 9338". Here's the table (yes, it's labeled Table 2, the RFC really says that π):
+=================+=====+==========================+================+
|Name |Label| Value Type |Description |
+=================+=====+==========================+================+
|Countersignature |11 | COSE_Countersignature / |V2 |
|version 2 | | [+ COSE_Countersignature |countersignature|
| | | ] |attribute |
+-----------------+-----+--------------------------+----------------+
|Countersignature0|12 | COSE_Countersignature0 |V2 Abbreviated |
|version 2 | | |Countersignature|
+-----------------+-----+--------------------------+----------------+
Table 2: New Common Header Parameters
IANA also updated the existing "Description" fields for "counter signature" (7) and "CounterSignature0" (9) so they now include the words "(Deprecated by RFC 9338)" π₯. Old vibes, but they're retired now π .
6. Security Considerations π
bestie, this part is SERIOUS π Please go read the Security Considerations section in [RFC9052] first, because all of that applies here too. Especially the bit about implementations protecting private key material. Guard those keys like they're your diary π
When either COSE_Encrypt or COSE_Mac is used and more than two parties share the key, data origin authentication is not provided π. Any party that knows the message-authentication key can compute a valid authentication tag. So the contents could have come from any one of the parties sharing that key. Not me being dramatic, it's just how it works π
Countersignatures of COSE_Encrypt and COSE_Mac with short authentication tags do NOT give you the same security properties as the same algorithm used in COSE_Sign. Hard stop π To get 128-bit security against collision attacks, the tag length MUST be at least 256 bits. A countersignature of a COSE_Mac with AES-MAC (using a 128-bit key or larger) gives you at most 64 bits of integrity protection. And a countersignature of a COSE_Encrypt with AES-CCM-16-64-128 gives you at most 32 bits. Short tags are giving "not enough protection" and it's not a vibe ππ₯
7. References π
7.1. Normative References
- [RFC2119]: Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997,
https://www.rfc-editor.org/info/rfc2119. - [RFC8174]: Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017,
https://www.rfc-editor.org/info/rfc8174. - [RFC9052]: Schaad, J., "CBOR Object Signing and Encryption (COSE): Structures and Process", STD 96, RFC 9052, DOI 10.17487/RFC9052, August 2022,
https://www.rfc-editor.org/info/rfc9052.
7.2. Informative References
- [CBORDIAG]: Bormann, C., "CBOR diagnostic utilities", commit 1952a04, September 2022,
https://github.com/cabo/cbor-diag. - [GROUP-OSCORE]: Tiloca, M., Selander, G., Palombini, F., Mattsson, J., and J. Park, "Group OSCORE - Secure Group Communication for CoAP", Work in Progress, Internet-Draft, draft-ietf-core-oscore-groupcomm-16, 24 October 2022,
https://datatracker.ietf.org/doc/html/draft-ietf-core-oscore-groupcomm-16. - [RFC4998]: Gondrom, T., Brandner, R., and U. Pordesch, "Evidence Record Syntax (ERS)", RFC 4998, DOI 10.17487/RFC4998, August 2007,
https://www.rfc-editor.org/info/rfc4998. - [RFC7252]: Shelby, Z., Hartke, K., and C. Bormann, "The Constrained Application Protocol (CoAP)", RFC 7252, DOI 10.17487/RFC7252, June 2014,
https://www.rfc-editor.org/info/rfc7252. - [RFC8152]: Schaad, J., "CBOR Object Signing and Encryption (COSE)", RFC 8152, DOI 10.17487/RFC8152, July 2017,
https://www.rfc-editor.org/info/rfc8152. - [RFC8610]: Birkholz, H., Vigano, C., and C. Bormann, "Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, June 2019,
https://www.rfc-editor.org/info/rfc8610. - [RFC8613]: Selander, G., Mattsson, J., Palombini, F., and L. Seitz, "Object Security for Constrained RESTful Environments (OSCORE)", RFC 8613, DOI 10.17487/RFC8613, July 2019,
https://www.rfc-editor.org/info/rfc8613. - [RFC8949]: Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020,
https://www.rfc-editor.org/info/rfc8949. - [STD90]: Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, December 2017,
https://www.rfc-editor.org/info/std90.
Appendix A. Examples π§
this appendix is a whole gallery of examples showing off the features and message types defined in this document πΌοΈβ¨ They're written in the extended CBOR diagnostic notation (defined in [RFC8610]) instead of a binary dump, because it's way easier to read π€
The examples are in CBOR diagnostic notation. There's a Ruby-based tool [CBORDIAG] that can convert between diagnostic notation and binary, and its webpage has installation instructions π οΈ
You can turn the diagnostic notation into binary files with this command line:
diag2cbor.rb < inputfile > outputfile
You can also pull the examples out of the XML version of this document with an XPath expression, since all of the sourcecode is tagged with the attribute type="cbor-diag". Depending on which XPath evaluator you're using, you might have to deal with > as an entity π
//sourcecode[@type='cbor-diag']/text()
This appendix uses these terms:
AES-GCM: AES Galois/Counter ModeCEK: content-encryption keyECDH: Elliptic Curve Diffie-HellmanECDH-ES: Elliptic Curve Diffie-Hellman Ephemeral StaticECDSA: Elliptic Curve Digital Signature AlgorithmEdDSA: Edwards-curve Digital Signature AlgorithmHKDF: HMAC-based Key Derivation FunctionHMAC: Hashed Message Authentication Code
A.1. Examples of Signed Messages βοΈ
A.1.1. Countersignature
this example uses:
- Signature Algorithm: ECDSA with SHA-256, Curve P-256
the same header parameters are used for both the signature and the countersignature π―
the binary file is 180 bytes big π¦
98(
[
/ protected / h'',
/ unprotected / {
/ countersign / 11:[
/ protected h'a10126' / << {
/ alg / 1:-7 / ECDSA 256 /
} >>,
/ unprotected / {
/ kid / 4: '11'
},
/ signature / h'5ac05e289d5d0e1b0a7f048a5d2b643813ded50bc9e4
9220f4f7278f85f19d4a77d655c9d3b51e805a74b099e1e085aacd97fc29d72f887e
8802bb6650cceb2c'
]
},
/ payload / 'This is the content.',
/ signatures / [
[
/ protected h'a10126' / << {
/ alg / 1:-7 / ECDSA 256 /
} >>,
/ unprotected / {
/ kid / 4: '11'
},
/ signature / h'e2aeafd40d69d19dfe6e52077c5d7ff4e408282cbefb
5d06cbf414af2e19d982ac45ac98b8544c908b4507de1e90b717c3d34816fe926a2b
98f53afd2fa0f30a'
]
]
]
)
A.2. Examples of Signed1 Messages πΈ
A.2.1. Countersignature
this example uses:
- Signature Algorithm: ECDSA with SHA-256, Curve P-256
- Countersignature Algorithm: ECDSA with SHA-512, Curve P-521
the binary file is 275 bytes π
18(
[
/ protected h'A201260300' / << {
/ alg / 1:-7, / ECDSA 256 /
/ ctyp / 3:0
} >>,
/ unprotected / {
/ kid / 4: '11',
/ countersign / 11: [
/ protected h'A1013823' / << {
/ alg / 1:-36 / ECDSA 512 /
} >>,
/ unprotected / {
/ kid / 4: 'bilbo.baggins@hobbiton.example'
},
/ signature / h'01B1291B0E60A79C459A4A9184A0D393E034B34AF069
A1CCA34F5A913AFFFF698002295FA9F8FCBFB6FDFF59132FC0C406E98754A98F1FBF
E81C03095F481856BC470170227206FA5BEE3C0431C56A66824E7AAF692985952E31
271434B2BA2E47A335C658B5E995AEB5D63CF2D0CED367D3E4CC8FFFD53B70D115BA
A9E86961FBD1A5CF'
]
},
/ payload / 'This is the content.',
/ signature / h'BB587D6B15F47BFD54D2CBFCECEF75451E92B08A514BD439
FA3AA65C6AC92DF0D7328C4A47529B32ADD3DD1B4E940071C021E9A8F2641F1D8E3B
053DDD65AE52'
]
)
A.3. Examples of Enveloped Messages π
A.3.1. Countersignature on Encrypted Content
this example uses:
- CEK: AES-GCM with 128-bit key
- Recipient Class: ECDH Ephemeral-Static, Curve P-256
- Countersignature Algorithm: ECDSA with SHA-512, Curve P-521
the binary file is 326 bytes π
96(
[
/ protected h'a10101' / << {
/ alg / 1:1 / AES-GCM 128 /
} >>,
/ unprotected / {
/ iv / 5:h'c9cf4df2fe6c632bf7886413',
/ countersign / 11:[
/ protected h'a1013823' / << {
/ alg / 1:-36 / ES512 /
} >>,
/ unprotected / {
/ kid / 4: 'bilbo.baggins@hobbiton.example'
},
/ signature / h'00929663c8789bb28177ae28467e66377da12302d7f9
594d2999afa5dfa531294f8896f2b6cdf1740014f4c7f1a358e3a6cf57f4ed6fb02f
cf8f7aa989f5dfd07f0700a3a7d8f3c604ba70fa9411bd10c2591b483e1d2c31de00
3183e434d8fba18f17a4c7e3dfa003ac1cf3d30d44d2533c4989d3ac38c38b71481c
c3430c9d65e7ddff'
]
},
/ ciphertext / h'7adbe2709ca818fb415f1e5df66f4e1a51053ba6d65a1a0
c52a357da7a644b8070a151b0',
/ recipients / [
[
/ protected h'a1013818' / << {
/ alg / 1:-25 / ECDH-ES + HKDF-256 /
} >>,
/ unprotected / {
/ ephemeral / -1:{
/ kty / 1:2,
/ crv / -1:1,
/ x / -2:h'98f50a4ff6c05861c8860d13a638ea56c3f5ad7590bbf
bf054e1c7b4d91d6280',
/ y / -3:true
},
/ kid / 4: 'meriadoc.brandybuck@buckland.example'
},
/ ciphertext / h''
]
]
]
)
A.4. Examples of Encrypted Messages π
A.4.1. Countersignature on Encrypted Content
this example uses:
- CEK: AES-GCM with 128-bit key
- Countersignature Algorithm: EdDSA with Curve Ed25519
the binary file is 136 bytes π¦
16(
[
/ protected h'A10101' / << {
/ alg / 1:1 / AES-GCM 128 /
} >>,
/ unprotected / {
/ iv / 5: h'02D1F7E6F26C43D4868D87CE',
/ countersign / 11: [
/ protected h'A10127' / << {
/ alg / 1:-8 / EdDSA with Ed25519 /
} >>,
/ unprotected / {
/ kid / 4: '11'
},
/ signature / h'E10439154CC75C7A3A5391491F88651E0292FD0FE0E0
2CF740547EAF6677B4A4040B8ECA16DB592881262F77B14C1A086C02268B17171CA1
6BE4B8595F8C0A08'
]
},
/ ciphertext / h'60973A94BB2898009EE52ECFD9AB1DD25867374B162E2C0
3568B41F57C3CC16F9166250A'
]
)
A.5. Examples of MACed Messages π
A.5.1. Countersignature on MAC Content β¨
okay so this one is a MACed message with a countersignature stacked on top π₯ bestie, we're doing HMAC/SHA-256 with a 256-bit key for the MAC, and the countersigner is EdDSA on Curve Ed25519 π
- MAC Algorithm: HMAC/SHA-256 with 256-bit key
- Countersignature Algorithm: EdDSA with Curve Ed25519
the binary file is 159 bytes, so tiny and cute π
97(
[
/ protected h'A10105' / << {
/ alg / 1:5 / HS256 /
} >>,
/ unprotected / {
/ countersign / 11: [
/ protected h'A10127' / << {
/ alg / 1:-8 / EdDSA /
} >>,
/ unprotected / {
/ kid / 4: '11'
},
/ signature / h'602566F4A311DC860740D2DF54D4864555E85BC036EA
5A6CF7905B96E499C5F66B01C4997F6A20C37C37543ADEA1D705347D38A5B13594B2
9583DD741F455101'
]
},
/ payload / 'This is the content.',
/ tag / h'2BDCC89F058216B8A208DDC6D8B54AA91F48BD63484986565105C9
AD5A6682F6',
/ recipients / [
[
/ protected / h'',
/ unprotected / {
/ alg / 1: -6, / direct /
/ kid / 4: 'our-secret'
},
/ ciphertext / h''
]
]
]
)
A.6. Examples of MAC0 Messages π§
MAC0 is the single-MAC version of the vibe, so now we're checking out how it looks with a countersignature on top π
A.6.1. Countersignature on MAC0 Content π¦
same energy as the last example, bestie. this one uses:
- MAC Algorithm: HMAC/SHA-256 with 256-bit key
- Countersignature Algorithm: EdDSA with Curve Ed25519
and the binary file is also 159 bytes, iconic π
17(
[
/ protected h'A10105' / << {
/ alg / 1:5 / HS256 /
} >>,
/ unprotected / {
/ countersign / 11: [
/ protected h'A10127' / << {
/ alg / 1:-8 / EdDSA /
} >>,
/ unprotected / {
/ kid / 4: '11'
},
/ signature / h'968A315DF6B4F26362E11F4CFD2F2F4E76232F39657B
F1598837FF9332CDDD7581E248116549451F81EF823DA5974F885B681D3D6E38FC41
42D8F8E9E7DC8F0D'
]
},
/ payload / 'This is the content.',
/ tag / h'A1A848D3471F9D61EE49018D244C824772F223AD4F935293F1789F
C3A08D8C58'
]
)
Acknowledgments π«Ά
okay bestie, big thank yous π this document is a product of the COSE Working Group of the IETF, so the COSE crew really did the thing π
the first draft of the spec was based to some degree on the outputs of the JOSE and S/MIME Working Groups, so shoutout to those groups too β¨
Jim Schaad passed on 3 October 2020. π this document is primarily his work, and he deserves all the credit for the technical content π Russ Housley stepped in as the document editor after Jim's untimely death, mostly helping with the approval and publication processes, which was so needed πΈ
Jim Schaad and Jonathan Hammell provided the examples in Appendix A π
the reviews by Carsten Bormann, Ben Kaduk, and Elwyn Davies seriously leveled up the clarity of the document π they're the reason it reads so well π
Author's Address πΈ
Jim Schaad August Cellars United States of America
π¦ where this page comes from
- ietf: rfc9338 2022-12
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms