HTTP Message Signatures
RFC 9421
Document | Type | RFC - Proposed Standard (February 2024) | |
---|---|---|---|
Authors | Annabelle Backman , Justin Richer , Manu Sporny | ||
Last updated | 2024-02-14 | ||
RFC stream | Internet Engineering Task Force (IETF) | ||
Formats | |||
Additional resources | Mailing list discussion | ||
IESG | Responsible AD | Paul Wouters | |
Send notices to | (None) |
RFC 9421
"example-header": value, with, lots, of, commas Since two semantically distinct inputs can create the same output in the signature base, special care has to be taken when handling such values. Specifically, the Set-Cookie field [COOKIE] defines an internal syntax that does not conform to the List syntax provided in [STRUCTURED-FIELDS]. In particular, some portions allow unquoted commas, and the field is typically sent as multiple separate field lines with distinct values when sending multiple cookies. When multiple Set-Cookie fields are sent in the same message, it is not generally possible to combine these into a single line and be able to parse and use the results, as discussed in [HTTP], Section 5.3. Therefore, all the cookies need to be processed from their separate field values, without being combined, while the signature base needs to be processed from the special combined value generated solely for this purpose. If the cookie value is invalid, the signed message ought to be rejected, as this is a possible padding attack as described in Section 7.5.7. To deal with this, an application can choose to limit signing of problematic fields like Set-Cookie, such as including the field in a signature only when a single field value is present and the results would be unambiguous. Similar caution needs to be taken with all fields that could have non-deterministic mappings into the signature base. Signers can also make use of the bs parameter to armor such fields, as described in Section 2.1.3. 7.5.7. Padding Attacks with Multiple Field Values Since HTTP field values need to be combined into a single string value to be included in the HTTP signature base (see Section 2.5), it is possible for an attacker to inject an additional value for a given field and add this to the signature base of the verifier. In most circumstances, this causes the signature validation to fail as expected, since the new signature base value will not match the one used by the signer to create the signature. However, it is theoretically possible for the attacker to inject both a garbage value into a field and a desired value into another field in order to force a particular input. This is a variation of the collision attack described in Section 7.3.1, where the attacker accomplishes their change in the message by adding to existing field values. To counter this, an application needs to validate the content of the fields covered in the signature in addition to ensuring that the signature itself validates. With such protections, the attacker's padding attack would be rejected by the field value processor, even in the case where the attacker could force a signature collision. 7.5.8. Ambiguous Handling of Query Elements The HTML form parameters format defined in Section 5 ("application/ x-www-form-urlencoded") of [HTMLURL] is widely deployed and supported by many application frameworks. For convenience, some of these frameworks in particular combine query parameters that are found in the HTTP query and those found in the message content, particularly for POST messages with a Content-Type value of "application/x-www- form-urlencoded". The @query-param derived component identifier defined in Section 2.2.8 draws its values only from the query section of the target URI of the request. As such, it would be possible for an attacker to shadow or replace query parameters in a request by overriding a signed query parameter with an unsigned form parameter, or vice versa. To counter this, an application needs to make sure that values used for the signature base and the application are drawn from a consistent context, in this case the query component of the target URI. Additionally, when the HTTP request has content, an application should sign the message content as well, as discussed in Section 7.2.8. 8. Privacy Considerations 8.1. Identification through Keys If a signer uses the same key with multiple verifiers or uses the same key over time with a single verifier, the ongoing use of that key can be used to track the signer throughout the set of verifiers that messages are sent to. Since cryptographic keys are meant to be functionally unique, the use of the same key over time is a strong indicator that it is the same party signing multiple messages. In many applications, this is a desirable trait, and it allows HTTP message signatures to be used as part of authenticating the signer to the verifier. However, it could also result in unintentional tracking that a signer might not be aware of. To counter this kind of tracking, a signer can use a different key for each verifier that it is in communication with. Sometimes, a signer could also rotate their key when sending messages to a given verifier. These approaches do not negate the need for other anti-tracking techniques to be applied as necessary. 8.2. Signatures do not provide confidentiality HTTP message signatures do not provide confidentiality for any of the information protected by the signature. The content of the HTTP message, including the value of all fields and the value of the signature itself, is presented in plaintext to any party with access to the message. To provide confidentiality at the transport level, TLS or its equivalent can be used, as discussed in Section 7.1.2. 8.3. Oracles It is important to balance the need for providing useful feedback to developers regarding error conditions without providing additional information to an attacker. For example, a naive but helpful server implementation might try to indicate the required key identifier needed for requesting a resource. If someone knows who controls that key, a correlation can be made between the resource's existence and the party identified by the key. Access to such information could be used by an attacker as a means to target the legitimate owner of the resource for further attacks. 8.4. Required Content A core design tenet of this specification is that all message components covered by the signature need to be available to the verifier in order to recreate the signature base and verify the signature. As a consequence, if an application of this specification requires that a particular field be signed, the verifier will need access to the value of that field. For example, in some complex systems with intermediary processors, this could cause surprising behavior where, for fear of breaking the signature, an intermediary cannot remove privacy-sensitive information from a message before forwarding it on for processing. One way to mitigate this specific situation would be for the intermediary to verify the signature itself and then modify the message to remove the privacy-sensitive information. The intermediary can add its own signature at this point to signal to the next destination that the incoming signature was validated, as shown in the example in Section 4.3. 9. References 9.1. Normative References [ABNF] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008, <https://www.rfc-editor.org/info/rfc5234>. [ASCII] Cerf, V., "ASCII format for network interchange", STD 80, RFC 20, DOI 10.17487/RFC0020, October 1969, <https://www.rfc-editor.org/info/rfc20>. [FIPS186-5] NIST, "Digital Signature Standard (DSS)", DOI 10.6028/NIST.FIPS.186-5, February 2023, <https://doi.org/10.6028/NIST.FIPS.186-5>. [HTMLURL] WHATWG, "URL (Living Standard)", January 2024, <https://url.spec.whatwg.org/>. [HTTP] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, June 2022, <https://www.rfc-editor.org/info/rfc9110>. [HTTP/1.1] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP/1.1", STD 99, RFC 9112, DOI 10.17487/RFC9112, June 2022, <https://www.rfc-editor.org/info/rfc9112>. [POSIX.1] IEEE, "The Open Group Base Specifications Issue 7, 2018 edition", 2018, <https://pubs.opengroup.org/onlinepubs/9699919799/>. [RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed- Hashing for Message Authentication", RFC 2104, DOI 10.17487/RFC2104, February 1997, <https://www.rfc-editor.org/info/rfc2104>. [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>. [RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)", RFC 6234, DOI 10.17487/RFC6234, May 2011, <https://www.rfc-editor.org/info/rfc6234>. [RFC7517] Jones, M., "JSON Web Key (JWK)", RFC 7517, DOI 10.17487/RFC7517, May 2015, <https://www.rfc-editor.org/info/rfc7517>. [RFC7518] Jones, M., "JSON Web Algorithms (JWA)", RFC 7518, DOI 10.17487/RFC7518, May 2015, <https://www.rfc-editor.org/info/rfc7518>. [RFC8017] Moriarty, K., Ed., Kaliski, B., Jonsson, J., and A. Rusch, "PKCS #1: RSA Cryptography Specifications Version 2.2", RFC 8017, DOI 10.17487/RFC8017, November 2016, <https://www.rfc-editor.org/info/rfc8017>. [RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital Signature Algorithm (EdDSA)", RFC 8032, DOI 10.17487/RFC8032, January 2017, <https://www.rfc-editor.org/info/rfc8032>. [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>. [STRUCTURED-FIELDS] Nottingham, M. and P. Kamp, "Structured Field Values for HTTP", RFC 8941, DOI 10.17487/RFC8941, February 2021, <https://www.rfc-editor.org/info/rfc8941>. [URI] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, <https://www.rfc-editor.org/info/rfc3986>. 9.2. Informative References [AWS-SIGv4] Amazon Simple Storage Service, "Authenticating Requests (AWS Signature Version 4)", March 2006, <https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4- authenticating-requests.html>. [BCP195] Moriarty, K. and S. Farrell, "Deprecating TLS 1.0 and TLS 1.1", BCP 195, RFC 8996, March 2021. Sheffer, Y., Saint-Andre, P., and T. Fossati, "Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS)", BCP 195, RFC 9325, November 2022. <https://www.rfc-editor.org/info/bcp195> [CLIENT-CERT] Campbell, B. and M. Bishop, "Client-Cert HTTP Header Field", RFC 9440, DOI 10.17487/RFC9440, July 2023, <https://www.rfc-editor.org/info/rfc9440>. [COOKIE] Barth, A., "HTTP State Management Mechanism", RFC 6265, DOI 10.17487/RFC6265, April 2011, <https://www.rfc-editor.org/info/rfc6265>. [DIGEST] Polli, R. and L. Pardue, "Digest Fields", RFC 9530, DOI 10.17487/RFC9530, February 2024, <https://www.rfc-editor.org/info/rfc9530>. [JACKSON2019] Jackson, D., Cremers, C., Cohn-Gordon, K., and R. Sasse, "Seems Legit: Automated Analysis of Subtle Attacks on Protocols that Use Signatures", CCS '19: Proceedings of the 2019 ACM SIGSAC Conference on Computer and Communications Security, pp. 2165-2180, DOI 10.1145/3319535.3339813, November 2019, <https://dl.acm.org/doi/10.1145/3319535.3339813>. [JWS] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May 2015, <https://www.rfc-editor.org/info/rfc7515>. [RFC7239] Petersson, A. and M. Nilsson, "Forwarded HTTP Extension", RFC 7239, DOI 10.17487/RFC7239, June 2014, <https://www.rfc-editor.org/info/rfc7239>. [RFC7468] Josefsson, S. and S. Leonard, "Textual Encodings of PKIX, PKCS, and CMS Structures", RFC 7468, DOI 10.17487/RFC7468, April 2015, <https://www.rfc-editor.org/info/rfc7468>. [RFC7807] Nottingham, M. and E. Wilde, "Problem Details for HTTP APIs", RFC 7807, DOI 10.17487/RFC7807, March 2016, <https://www.rfc-editor.org/info/rfc7807>. [RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, <https://www.rfc-editor.org/info/rfc8126>. [RFC8792] Watsen, K., Auerswald, E., Farrel, A., and Q. Wu, "Handling Long Lines in Content of Internet-Drafts and RFCs", RFC 8792, DOI 10.17487/RFC8792, June 2020, <https://www.rfc-editor.org/info/rfc8792>. [RFC9457] Nottingham, M., Wilde, E., and S. Dalal, "Problem Details for HTTP APIs", RFC 9457, DOI 10.17487/RFC9457, July 2023, <https://www.rfc-editor.org/info/rfc9457>. [SIGNING-HTTP-MESSAGES] Cavage, M. and M. Sporny, "Signing HTTP Messages", Work in Progress, Internet-Draft, draft-cavage-http-signatures-12, 21 October 2019, <https://datatracker.ietf.org/doc/html/ draft-cavage-http-signatures-12>. [SIGNING-HTTP-REQS-OAUTH] Richer, J., Ed., Bradley, J., and H. Tschofenig, "A Method for Signing HTTP Requests for OAuth", Work in Progress, Internet-Draft, draft-ietf-oauth-signed-http-request-03, 8 August 2016, <https://datatracker.ietf.org/doc/html/draft- ietf-oauth-signed-http-request-03>. [TLS] Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>. Appendix A. Detecting HTTP Message Signatures There have been many attempts to create signed HTTP messages in the past, including other non-standardized definitions of the Signature field that is used within this specification. It is recommended that developers wishing to support this specification, other published documents, or other historical drafts do so carefully and deliberately, as incompatibilities between this specification and other documents or various versions of other drafts could lead to unexpected problems. It is recommended that implementors first detect and validate the Signature-Input field defined in this specification to detect that the mechanism described in this document is in use and not an alternative. If the Signature-Input field is present, all Signature fields can be parsed and interpreted in the context of this specification. Appendix B. Examples The following non-normative examples are provided as a means of testing implementations of HTTP message signatures. The signed messages given can be used to create the signature base with the stated parameters, creating signatures using the stated algorithms and keys. The private keys given can be used to generate signatures, though since several of the demonstrated algorithms are non-deterministic, the results of a signature are expected to be different from the exact bytes of the examples. The public keys given can be used to validate all signed examples. B.1. Example Keys This section provides cryptographic keys that are referenced in example signatures throughout this document. These keys MUST NOT be used for any purpose other than testing. The key identifiers for each key are used throughout the examples in this specification. It is assumed for these examples that the signer and verifier can unambiguously dereference all key identifiers used here and that the keys and algorithms used are appropriate for the context in which the signature is presented. The components for each private key, in PEM format [RFC7468], can be displayed by executing the following OpenSSL command: openssl pkey -text This command was tested with all the example keys on OpenSSL version 1.1.1m. Note that some systems cannot produce or use all of these keys directly and may require additional processing. All keys are also made available in JWK format. B.1.1. Example RSA Key The following key is a 2048-bit RSA public and private key pair, referred to in this document as test-key-rsa. This key is encoded in PEM format, with no encryption. -----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEAhAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrw WEBnez6d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFq MGmXCQvEG7YemcxDTRPxAleIAgYYRjTSd/QBwVW9OwNFhekro3RtlinV0a75jfZg kne/YiktSvLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0P uKxI4T+HIaFpv8+rdV6eUgOrB2xeI1dSFFn/nnv5OoZJEIB+VmuKn3DCUcCZSFlQ PSXSfBDiUGhwOw76WuSSsf1D4b/vLoJ10wIDAQAB -----END RSA PUBLIC KEY----- -----BEGIN RSA PRIVATE KEY----- MIIEqAIBAAKCAQEAhAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsP BRrwWEBnez6d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsd JKFqMGmXCQvEG7YemcxDTRPxAleIAgYYRjTSd/QBwVW9OwNFhekro3RtlinV0a75 jfZgkne/YiktSvLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKI lE0PuKxI4T+HIaFpv8+rdV6eUgOrB2xeI1dSFFn/nnv5OoZJEIB+VmuKn3DCUcCZ SFlQPSXSfBDiUGhwOw76WuSSsf1D4b/vLoJ10wIDAQABAoIBAG/JZuSWdoVHbi56 vjgCgkjg3lkO1KrO3nrdm6nrgA9P9qaPjxuKoWaKO1cBQlE1pSWp/cKncYgD5WxE CpAnRUXG2pG4zdkzCYzAh1i+c34L6oZoHsirK6oNcEnHveydfzJL5934egm6p8DW +m1RQ70yUt4uRc0YSor+q1LGJvGQHReF0WmJBZHrhz5e63Pq7lE0gIwuBqL8SMaA yRXtK+JGxZpImTq+NHvEWWCu09SCq0r838ceQI55SvzmTkwqtC+8AT2zFviMZkKR Qo6SPsrqItxZWRty2izawTF0Bf5S2VAx7O+6t3wBsQ1sLptoSgX3QblELY5asI0J YFz7LJECgYkAsqeUJmqXE3LP8tYoIjMIAKiTm9o6psPlc8CrLI9CH0UbuaA2JCOM cCNq8SyYbTqgnWlB9ZfcAm/cFpA8tYci9m5vYK8HNxQr+8FS3Qo8N9RJ8d0U5Csw DzMYfRghAfUGwmlWj5hp1pQzAuhwbOXFtxKHVsMPhz1IBtF9Y8jvgqgYHLbmyiu1 mwJ5AL0pYF0G7x81prlARURwHo0Yf52kEw1dxpx+JXER7hQRWQki5/NsUEtv+8RT qn2m6qte5DXLyn83b1qRscSdnCCwKtKWUug5q2ZbwVOCJCtmRwmnP131lWRYfj67 B/xJ1ZA6X3GEf4sNReNAtaucPEelgR2nsN0gKQKBiGoqHWbK1qYvBxX2X3kbPDkv 9C+celgZd2PW7aGYLCHq7nPbmfDV0yHcWjOhXZ8jRMjmANVR/eLQ2EfsRLdW69bn f3ZD7JS1fwGnO3exGmHO3HZG+6AvberKYVYNHahNFEw5TsAcQWDLRpkGybBcxqZo 81YCqlqidwfeO5YtlO7etx1xLyqa2NsCeG9A86UjG+aeNnXEIDk1PDK+EuiThIUa /2IxKzJKWl1BKr2d4xAfR0ZnEYuRrbeDQYgTImOlfW6/GuYIxKYgEKCFHFqJATAG IxHrq1PDOiSwXd2GmVVYyEmhZnbcp8CxaEMQoevxAta0ssMK3w6UsDtvUvYvF22m qQKBiD5GwESzsFPy3Ga0MvZpn3D6EJQLgsnrtUPZx+z2Ep2x0xc5orneB5fGyF1P WtP+fG5Q6Dpdz3LRfm+KwBCWFKQjg7uTxcjerhBWEYPmEMKYwTJF5PBG9/ddvHLQ EQeNC8fHGg4UXU8mhHnSBt3EA10qQJfRDs15M38eG2cYwB1PZpDHScDnDA0= -----END RSA PRIVATE KEY----- The same public and private key pair in JWK format: NOTE: '\' line wrapping per RFC 8792 { "kty": "RSA", "kid": "test-key-rsa", "p": "sqeUJmqXE3LP8tYoIjMIAKiTm9o6psPlc8CrLI9CH0UbuaA2JCOMcCNq8Sy\ YbTqgnWlB9ZfcAm_cFpA8tYci9m5vYK8HNxQr-8FS3Qo8N9RJ8d0U5CswDzMYfRgh\ AfUGwmlWj5hp1pQzAuhwbOXFtxKHVsMPhz1IBtF9Y8jvgqgYHLbmyiu1mw", "q": "vSlgXQbvHzWmuUBFRHAejRh_naQTDV3GnH4lcRHuFBFZCSLn82xQS2_7xFO\ qfabqq17kNcvKfzdvWpGxxJ2cILAq0pZS6DmrZlvBU4IkK2ZHCac_XfWVZFh-PrsH\ _EnVkDpfcYR_iw1F40C1q5w8R6WBHaew3SAp", "d": "b8lm5JZ2hUduLnq-OAKCSODeWQ7Uqs7eet2bqeuAD0_2po-PG4qhZoo7VwF\ CUTWlJan9wqdxiAPlbEQKkCdFRcbakbjN2TMJjMCHWL5zfgvqhmgeyKsrqg1wSce9\ 7J1_Mkvn3fh6CbqnwNb6bVFDvTJS3i5FzRhKiv6rUsYm8ZAdF4XRaYkFkeuHPl7rc\ -ruUTSAjC4GovxIxoDJFe0r4kbFmkiZOr40e8RZYK7T1IKrSvzfxx5AjnlK_OZOTC\ q0L7wBPbMW-IxmQpFCjpI-yuoi3FlZG3LaLNrBMXQF_lLZUDHs77q3fAGxDWwum2h\ KBfdBuUQtjlqwjQlgXPsskQ", "e": "AQAB", "qi": "PkbARLOwU_LcZrQy9mmfcPoQlAuCyeu1Q9nH7PYSnbHTFzmiud4Hl8bIXU\ 9a0_58blDoOl3PctF-b4rAEJYUpCODu5PFyN6uEFYRg-YQwpjBMkXk8Eb39128ctA\ RB40Lx8caDhRdTyaEedIG3cQDXSpAl9EOzXkzfx4bZxjAHU9mkMdJwOcMDQ", "dp": "aiodZsrWpi8HFfZfeRs8OS_0L5x6WBl3Y9btoZgsIeruc9uZ8NXTIdxaM6\ FdnyNEyOYA1VH94tDYR-xEt1br1ud_dkPslLV_Aac7d7EaYc7cdkb7oC9t6sphVg0\ dqE0UTDlOwBxBYMtGmQbJsFzGpmjzVgKqWqJ3B947li2U7t63HXEvKprY2w", "dq": "b0DzpSMb5p42dcQgOTU8Mr4S6JOEhRr_YjErMkpaXUEqvZ3jEB9HRmcRi5\ Gtt4NBiBMiY6V9br8a5gjEpiAQoIUcWokBMAYjEeurU8M6JLBd3YaZVVjISaFmdty\ nwLFoQxCh6_EC1rSywwrfDpSwO29S9i8Xbaap", "n": "hAKYdtoeoy8zcAcR874L8cnZxKzAGwd7v36APp7Pv6Q2jdsPBRrwWEBnez6\ d0UDKDwGbc6nxfEXAy5mbhgajzrw3MOEt8uA5txSKobBpKDeBLOsdJKFqMGmXCQvE\ G7YemcxDTRPxAleIAgYYRjTSd_QBwVW9OwNFhekro3RtlinV0a75jfZgkne_YiktS\ vLG34lw2zqXBDTC5NHROUqGTlML4PlNZS5Ri2U4aCNx2rUPRcKIlE0PuKxI4T-HIa\ Fpv8-rdV6eUgOrB2xeI1dSFFn_nnv5OoZJEIB-VmuKn3DCUcCZSFlQPSXSfBDiUGh\ wOw76WuSSsf1D4b_vLoJ10w" } B.1.2. Example RSA-PSS Key The following key is a 2048-bit RSA public and private key pair, referred to in this document as test-key-rsa-pss. This key is PKCS #8 encoded in PEM format, with no encryption. -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr4tmm3r20Wd/PbqvP1s2 +QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvMs8ct+Lh1GH45x28Rw3Ry53mm+ oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95AndTrifbIFPNU8PPMO7OyrFAHq gDsznjPFmTOtCEcN2Z1FpWgchwuYLPL+Wokqltd11nqqzi+bJ9cvSKADYdUAAN5W Utzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSyZYoA485mqcO0GVAdVw9lq4 aOT9v6d+nb4bnNkQVklLQ3fVAvJm+xdDOp9LCNCN48V2pnDOkFV6+U9nV5oyc6XI 2wIDAQAB -----END PUBLIC KEY----- -----BEGIN PRIVATE KEY----- MIIEvgIBADALBgkqhkiG9w0BAQoEggSqMIIEpgIBAAKCAQEAr4tmm3r20Wd/Pbqv P1s2+QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvMs8ct+Lh1GH45x28Rw3Ry5 3mm+oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95AndTrifbIFPNU8PPMO7Oyr FAHqgDsznjPFmTOtCEcN2Z1FpWgchwuYLPL+Wokqltd11nqqzi+bJ9cvSKADYdUA AN5WUtzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSyZYoA485mqcO0GVAdVw 9lq4aOT9v6d+nb4bnNkQVklLQ3fVAvJm+xdDOp9LCNCN48V2pnDOkFV6+U9nV5oy c6XI2wIDAQABAoIBAQCUB8ip+kJiiZVKF8AqfB/aUP0jTAqOQewK1kKJ/iQCXBCq pbo360gvdt05H5VZ/RDVkEgO2k73VSsbulqezKs8RFs2tEmU+JgTI9MeQJPWcP6X aKy6LIYs0E2cWgp8GADgoBs8llBq0UhX0KffglIeek3n7Z6Gt4YFge2TAcW2WbN4 XfK7lupFyo6HHyWRiYHMMARQXLJeOSdTn5aMBP0PO4bQyk5ORxTUSeOciPJUFktQ HkvGbym7KryEfwH8Tks0L7WhzyP60PL3xS9FNOJi9m+zztwYIXGDQuKM2GDsITeD 2mI2oHoPMyAD0wdI7BwSVW18p1h+jgfc4dlexKYRAoGBAOVfuiEiOchGghV5vn5N RDNscAFnpHj1QgMr6/UG05RTgmcLfVsI1I4bSkbrIuVKviGGf7atlkROALOG/xRx DLadgBEeNyHL5lz6ihQaFJLVQ0u3U4SB67J0YtVO3R6lXcIjBDHuY8SjYJ7Ci6Z6 vuDcoaEujnlrtUhaMxvSfcUJAoGBAMPsCHXte1uWNAqYad2WdLjPDlKtQJK1diCm rqmB2g8QE99hDOHItjDBEdpyFBKOIP+NpVtM2KLhRajjcL9Ph8jrID6XUqikQuVi 4J9FV2m42jXMuioTT13idAILanYg8D3idvy/3isDVkON0X3UAVKrgMEne0hJpkPL FYqgetvDAoGBAKLQ6JZMbSe0pPIJkSamQhsehgL5Rs51iX4m1z7+sYFAJfhvN3Q/ OGIHDRp6HjMUcxHpHw7U+S1TETxePwKLnLKj6hw8jnX2/nZRgWHzgVcY+sPsReRx NJVf+Cfh6yOtznfX00p+JWOXdSY8glSSHJwRAMog+hFGW1AYdt7w80XBAoGBAImR NUugqapgaEA8TrFxkJmngXYaAqpA0iYRA7kv3S4QavPBUGtFJHBNULzitydkNtVZ 3w6hgce0h9YThTo/nKc+OZDZbgfN9s7cQ75x0PQCAO4fx2P91Q+mDzDUVTeG30mE t2m3S0dGe47JiJxifV9P3wNBNrZGSIF3mrORBVNDAoGBAI0QKn2Iv7Sgo4T/XjND dl2kZTXqGAk8dOhpUiw/HdM3OGWbhHj2NdCzBliOmPyQtAr770GITWvbAI+IRYyF S7Fnk6ZVVVHsxjtaHy1uJGFlaZzKR4AGNaUTOJMs6NadzCmGPAxNQQOCqoUjn4XR rOjr9w349JooGXhOxbu8nOxX -----END PRIVATE KEY----- The same public and private key pair in JWK format: NOTE: '\' line wrapping per RFC 8792 { "kty": "RSA", "kid": "test-key-rsa-pss", "p": "5V-6ISI5yEaCFXm-fk1EM2xwAWekePVCAyvr9QbTlFOCZwt9WwjUjhtKRus\ i5Uq-IYZ_tq2WRE4As4b_FHEMtp2AER43IcvmXPqKFBoUktVDS7dThIHrsnRi1U7d\ HqVdwiMEMe5jxKNgnsKLpnq-4NyhoS6OeWu1SFozG9J9xQk", "q": "w-wIde17W5Y0Cphp3ZZ0uM8OUq1AkrV2IKauqYHaDxAT32EM4ci2MMER2nI\ UEo4g_42lW0zYouFFqONwv0-HyOsgPpdSqKRC5WLgn0VXabjaNcy6KhNPXeJ0Agtq\ diDwPeJ2_L_eKwNWQ43RfdQBUquAwSd7SEmmQ8sViqB628M", "d": "lAfIqfpCYomVShfAKnwf2lD9I0wKjkHsCtZCif4kAlwQqqW6N-tIL3bdOR-\ VWf0Q1ZBIDtpO91UrG7pansyrPERbNrRJlPiYEyPTHkCT1nD-l2isuiyGLNBNnFoK\ fBgA4KAbPJZQatFIV9Cn34JSHnpN5-2ehreGBYHtkwHFtlmzeF3yu5bqRcqOhx8lk\ YmBzDAEUFyyXjknU5-WjAT9DzuG0MpOTkcU1EnjnIjyVBZLUB5Lxm8puyq8hH8B_E\ 5LNC-1oc8j-tDy98UvRTTiYvZvs87cGCFxg0LijNhg7CE3g9piNqB6DzMgA9MHSOw\ cElVtfKdYfo4H3OHZXsSmEQ", "e": "AQAB", "qi": "jRAqfYi_tKCjhP9eM0N2XaRlNeoYCTx06GlSLD8d0zc4ZZuEePY10LMGWI\ 6Y_JC0CvvvQYhNa9sAj4hFjIVLsWeTplVVUezGO1ofLW4kYWVpnMpHgAY1pRM4kyz\ o1p3MKYY8DE1BA4KqhSOfhdGs6Ov3Dfj0migZeE7Fu7yc7Fc", "dp": "otDolkxtJ7Sk8gmRJqZCGx6GAvlGznWJfibXPv6xgUAl-G83dD84YgcNGn\ oeMxRzEekfDtT5LVMRPF4_AoucsqPqHDyOdfb-dlGBYfOBVxj6w-xF5HE0lV_4J-H\ rI63Od9fTSn4lY5d1JjyCVJIcnBEAyiD6EUZbUBh23vDzRcE", "dq": "iZE1S6CpqmBoQDxOsXGQmaeBdhoCqkDSJhEDuS_dLhBq88FQa0UkcE1QvO\ K3J2Q21VnfDqGBx7SH1hOFOj-cpz45kNluB832ztxDvnHQ9AIA7h_HY_3VD6YPMNR\ VN4bfSYS3abdLR0Z7jsmInGJ9X0_fA0E2tkZIgXeas5EFU0M", "n": "r4tmm3r20Wd_PbqvP1s2-QEtvpuRaV8Yq40gjUR8y2Rjxa6dpG2GXHbPfvM\ s8ct-Lh1GH45x28Rw3Ry53mm-oAXjyQ86OnDkZ5N8lYbggD4O3w6M6pAvLkhk95An\ dTrifbIFPNU8PPMO7OyrFAHqgDsznjPFmTOtCEcN2Z1FpWgchwuYLPL-Wokqltd11\ nqqzi-bJ9cvSKADYdUAAN5WUtzdpiy6LbTgSxP7ociU4Tn0g5I6aDZJ7A8Lzo0KSy\ ZYoA485mqcO0GVAdVw9lq4aOT9v6d-nb4bnNkQVklLQ3fVAvJm-xdDOp9LCNCN48V\ 2pnDOkFV6-U9nV5oyc6XI2w" } B.1.3. Example ECC P-256 Test Key The following key is a public and private elliptical curve key pair over the curve P-256, referred to in this document as test-key-ecc- p256. This key is encoded in PEM format, with no encryption. -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lf w0EkjqF7xB4FivAxzic30tMM4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== -----END PUBLIC KEY----- -----BEGIN EC PRIVATE KEY----- MHcCAQEEIFKbhfNZfpDsW43+0+JjUr9K+bTeuxopu653+hBaXGA7oAoGCCqGSM49 AwEHoUQDQgAEqIVYZVLCrPZHGHjP17CTW0/+D9Lfw0EkjqF7xB4FivAxzic30tMM 4GF+hR6Dxh71Z50VGGdldkkDXZCnTNnoXQ== -----END EC PRIVATE KEY----- The same public and private key pair in JWK format: { "kty": "EC", "crv": "P-256", "kid": "test-key-ecc-p256", "d": "UpuF81l-kOxbjf7T4mNSv0r5tN67Gim7rnf6EFpcYDs", "x": "qIVYZVLCrPZHGHjP17CTW0_-D9Lfw0EkjqF7xB4FivA", "y": "Mc4nN9LTDOBhfoUeg8Ye9WedFRhnZXZJA12Qp0zZ6F0" } B.1.4. Example Ed25519 Test Key The following key is an elliptical curve key over the Edwards curve ed25519, referred to in this document as test-key-ed25519. This key is PKCS #8 encoded in PEM format, with no encryption. -----BEGIN PUBLIC KEY----- MCowBQYDK2VwAyEAJrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs= -----END PUBLIC KEY----- -----BEGIN PRIVATE KEY----- MC4CAQAwBQYDK2VwBCIEIJ+DYvh6SEqVTm50DFtMDoQikTmiCqirVv9mWG9qfSnF -----END PRIVATE KEY----- The same public and private key pair in JWK format: { "kty": "OKP", "crv": "Ed25519", "kid": "test-key-ed25519", "d": "n4Ni-HpISpVObnQMW0wOhCKROaIKqKtW_2ZYb2p9KcU", "x": "JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs" } B.1.5. Example Shared Secret The following shared secret is 64 randomly generated bytes encoded in Base64, referred to in this document as test-shared-secret: NOTE: '\' line wrapping per RFC 8792 uzvJfB4u3N0Jy4T7NZ75MDVcr8zSTInedJtkgcu46YW4XByzNJjxBdtjUkdJPBt\ bmHhIDi6pcl8jsasjlTMtDQ== B.2. Test Cases This section provides non-normative examples that may be used as test cases to validate implementation correctness. These examples are based on the following HTTP messages: For requests, this test-request message is used: NOTE: '\' line wrapping per RFC 8792 POST /foo?param=Value&Pet=dog HTTP/1.1 Host: example.com Date: Tue, 20 Apr 2021 02:07:55 GMT Content-Type: application/json Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\ aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: Content-Length: 18 {"hello": "world"} For responses, this test-response message is used: NOTE: '\' line wrapping per RFC 8792 HTTP/1.1 200 OK Date: Tue, 20 Apr 2021 02:07:56 GMT Content-Type: application/json Content-Digest: sha-512=:mEWXIS7MaLRuGgxOBdODa3xqM1XdEvxoYhvlCFJ41Q\ JgJc4GTsPp29l5oGX69wWdXymyU0rjJuahq4l5aGgfLQ==: Content-Length: 23 {"message": "good dog"} B.2.1. Minimal Signature Using rsa-pss-sha512 This example presents a minimal signature using the rsa-pss-sha512 algorithm over test-request, covering none of the components of the HTTP message but providing a timestamped signature proof of possession of the key with a signer-provided nonce. The corresponding signature base is: NOTE: '\' line wrapping per RFC 8792 "@signature-params": ();created=1618884473;keyid="test-key-rsa-pss"\ ;nonce="b3k2pp5k7z-50gnwp.yemd" This results in the following Signature-Input and Signature header fields being added to the message under the signature label sig-b21: NOTE: '\' line wrapping per RFC 8792 Signature-Input: sig-b21=();created=1618884473\ ;keyid="test-key-rsa-pss";nonce="b3k2pp5k7z-50gnwp.yemd" Signature: sig-b21=:d2pmTvmbncD3xQm8E9ZV2828BjQWGgiwAaw5bAkgibUopem\ LJcWDy/lkbbHAve4cRAtx31Iq786U7it++wgGxbtRxf8Udx7zFZsckzXaJMkA7ChG\ 52eSkFxykJeNqsrWH5S+oxNFlD4dzVuwe8DhTSja8xxbR/Z2cOGdCbzR72rgFWhzx\ 2VjBqJzsPLMIQKhO4DGezXehhWwE56YCE+O6c0mKZsfxVrogUvA4HELjVKWmAvtl6\ UnCh8jYzuVG5WSb/QEVPnP5TmcAnLH1g+s++v6d4s8m0gCw1fV5/SITLq9mhho8K3\ +7EPYTU8IU1bLhdxO5Nyt8C8ssinQ98Xw9Q==: Note that since the covered components list is empty, this signature could be applied by an attacker to an unrelated HTTP message. In this example, the nonce parameter is included to prevent the same signature from being replayed more than once, but if an attacker intercepts the signature and prevents its delivery to the verifier, the attacker could apply this signature to another message. Therefore, the use of an empty covered components set is discouraged. See Section 7.2.1 for more discussion. Note that the RSA-PSS algorithm in use here is non-deterministic, meaning that a different signature value will be created every time the algorithm is run. The signature value provided here can be validated against the given keys, but newly generated signature values are not expected to match the example. See Section 7.3.5. B.2.2. Selective Covered Components Using rsa-pss-sha512 This example covers additional components (the authority, the Content-Digest header field, and a single named query parameter) in test-request using the rsa-pss-sha512 algorithm. This example also adds a tag parameter with the application-specific value of header- example. The corresponding signature base is: NOTE: '\' line wrapping per RFC 8792 "@authority": example.com "content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ +TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: "@query-param";name="Pet": dog "@signature-params": ("@authority" "content-digest" \ "@query-param";name="Pet")\ ;created=1618884473;keyid="test-key-rsa-pss"\ ;tag="header-example" This results in the following Signature-Input and Signature header fields being added to the message under the label sig-b22: NOTE: '\' line wrapping per RFC 8792 Signature-Input: sig-b22=("@authority" "content-digest" \ "@query-param";name="Pet");created=1618884473\ ;keyid="test-key-rsa-pss";tag="header-example" Signature: sig-b22=:LjbtqUbfmvjj5C5kr1Ugj4PmLYvx9wVjZvD9GsTT4F7GrcQ\ EdJzgI9qHxICagShLRiLMlAJjtq6N4CDfKtjvuJyE5qH7KT8UCMkSowOB4+ECxCmT\ 8rtAmj/0PIXxi0A0nxKyB09RNrCQibbUjsLS/2YyFYXEu4TRJQzRw1rLEuEfY17SA\ RYhpTlaqwZVtR8NV7+4UKkjqpcAoFqWFQh62s7Cl+H2fjBSpqfZUJcsIk4N6wiKYd\ 4je2U/lankenQ99PZfB4jY3I5rSV2DSBVkSFsURIjYErOs0tFTQosMTAoxk//0RoK\ UqiYY8Bh0aaUEb0rQl3/XaVe4bXTugEjHSw==: Note that the RSA-PSS algorithm in use here is non-deterministic, meaning that a different signature value will be created every time the algorithm is run. The signature value provided here can be validated against the given keys, but newly generated signature values are not expected to match the example. See Section 7.3.5. B.2.3. Full Coverage Using rsa-pss-sha512 This example covers all applicable message components in test-request (including the content type and length) plus many derived components, again using the rsa-pss-sha512 algorithm. Note that the Host header field is not covered because the @authority derived component is included instead. The corresponding signature base is: NOTE: '\' line wrapping per RFC 8792 "date": Tue, 20 Apr 2021 02:07:55 GMT "@method": POST "@path": /foo "@query": ?param=Value&Pet=dog "@authority": example.com "content-type": application/json "content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX\ +TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: "content-length": 18 "@signature-params": ("date" "@method" "@path" "@query" \ "@authority" "content-type" "content-digest" "content-length")\ ;created=1618884473;keyid="test-key-rsa-pss" This results in the following Signature-Input and Signature header fields being added to the message under the label sig-b23: NOTE: '\' line wrapping per RFC 8792 Signature-Input: sig-b23=("date" "@method" "@path" "@query" \ "@authority" "content-type" "content-digest" "content-length")\ ;created=1618884473;keyid="test-key-rsa-pss" Signature: sig-b23=:bbN8oArOxYoyylQQUU6QYwrTuaxLwjAC9fbY2F6SVWvh0yB\ iMIRGOnMYwZ/5MR6fb0Kh1rIRASVxFkeGt683+qRpRRU5p2voTp768ZrCUb38K0fU\ xN0O0iC59DzYx8DFll5GmydPxSmme9v6ULbMFkl+V5B1TP/yPViV7KsLNmvKiLJH1\ pFkh/aYA2HXXZzNBXmIkoQoLd7YfW91kE9o/CCoC1xMy7JA1ipwvKvfrs65ldmlu9\ bpG6A9BmzhuzF8Eim5f8ui9eH8LZH896+QIF61ka39VBrohr9iyMUJpvRX2Zbhl5Z\ JzSRxpJyoEZAFL2FUo5fTIztsDZKEgM4cUA==: Note in this example that the value of the Date header field and the value of the created signature parameter need not be the same. This is due to the fact that the Date header field is added when creating the HTTP message and the created parameter is populated when creating the signature over that message, and these two times could vary. If the Date header field is covered by the signature, it is up to the verifier to determine whether its value has to match that of the created parameter or not. See Section 7.2.4 for more discussion. Note that the RSA-PSS algorithm in use here is non-deterministic, meaning that a different signature value will be created every time the algorithm is run. The signature value provided here can be validated against the given keys, but newly generated signature values are not expected to match the example. See Section 7.3.5. B.2.4. Signing a Response Using ecdsa-p256-sha256 This example covers portions of the test-response message using the ecdsa-p256-sha256 algorithm and the key test-key-ecc-p256. The corresponding signature base is: NOTE: '\' line wrapping per RFC 8792 "@status": 200 "content-type": application/json "content-digest": sha-512=:mEWXIS7MaLRuGgxOBdODa3xqM1XdEvxoYhvlCFJ4\ 1QJgJc4GTsPp29l5oGX69wWdXymyU0rjJuahq4l5aGgfLQ==: "content-length": 23 "@signature-params": ("@status" "content-type" "content-digest" \ "content-length");created=1618884473;keyid="test-key-ecc-p256" This results in the following Signature-Input and Signature header fields being added to the message under the label sig-b24: NOTE: '\' line wrapping per RFC 8792 Signature-Input: sig-b24=("@status" "content-type" \ "content-digest" "content-length");created=1618884473\ ;keyid="test-key-ecc-p256" Signature: sig-b24=:wNmSUAhwb5LxtOtOpNa6W5xj067m5hFrj0XQ4fvpaCLx0NK\ ocgPquLgyahnzDnDAUy5eCdlYUEkLIj+32oiasw==: Note that the ECDSA signature algorithm in use here is non- deterministic, meaning that a different signature value will be created every time the algorithm is run. The signature value provided here can be validated against the given keys, but newly generated signature values are not expected to match the example. See Section 7.3.5. B.2.5. Signing a Request Using hmac-sha256 This example covers portions of the test-request message using the hmac-sha256 algorithm and the secret test-shared-secret. The corresponding signature base is: NOTE: '\' line wrapping per RFC 8792 "date": Tue, 20 Apr 2021 02:07:55 GMT "@authority": example.com "content-type": application/json "@signature-params": ("date" "@authority" "content-type")\ ;created=1618884473;keyid="test-shared-secret" This results in the following Signature-Input and Signature header fields being added to the message under the label sig-b25: NOTE: '\' line wrapping per RFC 8792 Signature-Input: sig-b25=("date" "@authority" "content-type")\ ;created=1618884473;keyid="test-shared-secret" Signature: sig-b25=:pxcQw6G3AjtMBQjwo8XzkZf/bws5LelbaMk5rGIGtE8=: Before using symmetric signatures in practice, see the discussion regarding security trade-offs in Section 7.3.3. B.2.6. Signing a Request Using ed25519 This example covers portions of the test-request message using the Ed25519 algorithm and the key test-key-ed25519. The corresponding signature base is: NOTE: '\' line wrapping per RFC 8792 "date": Tue, 20 Apr 2021 02:07:55 GMT "@method": POST "@path": /foo "@authority": example.com "content-type": application/json "content-length": 18 "@signature-params": ("date" "@method" "@path" "@authority" \ "content-type" "content-length");created=1618884473\ ;keyid="test-key-ed25519" This results in the following Signature-Input and Signature header fields being added to the message under the label sig-b26: NOTE: '\' line wrapping per RFC 8792 Signature-Input: sig-b26=("date" "@method" "@path" "@authority" \ "content-type" "content-length");created=1618884473\ ;keyid="test-key-ed25519" Signature: sig-b26=:wqcAqbmYJ2ji2glfAMaRy4gruYYnx2nEFN2HN6jrnDnQCK1\ u02Gb04v9EDgwUPiu4A0w6vuQv5lIp5WPpBKRCw==: B.3. TLS-Terminating Proxies In this example, there is a TLS-terminating reverse proxy sitting in front of the resource. The client does not sign the request but instead uses mutual TLS to make its call. The terminating proxy validates the TLS stream and injects a Client-Cert header field according to [CLIENT-CERT], and then applies a signature to this field. By signing this header field, a reverse proxy not only can attest to its own validation of the initial request's TLS parameters but can also authenticate itself to the backend system independently of the client's actions. The client makes the following request to the TLS-terminating proxy using mutual TLS: POST /foo?param=Value&Pet=dog HTTP/1.1 Host: example.com Date: Tue, 20 Apr 2021 02:07:55 GMT Content-Type: application/json Content-Length: 18 {"hello": "world"} The proxy processes the TLS connection and extracts the client's TLS certificate to a Client-Cert header field and passes it along to the internal service hosted at service.internal.example. This results in the following unsigned request: NOTE: '\' line wrapping per RFC 8792 POST /foo?param=Value&Pet=dog HTTP/1.1 Host: service.internal.example Date: Tue, 20 Apr 2021 02:07:55 GMT Content-Type: application/json Content-Length: 18 Client-Cert: :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQKD\ BJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBDQT\ AeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDMFk\ wEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXmck\ C8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQYDV\ R0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8BAf\ 8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQGV\ 4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0Q6\ bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: {"hello": "world"} Without a signature, the internal service would need to trust that the incoming connection has the right information. By signing the Client-Cert header field and other portions of the internal request, the internal service can be assured that the correct party, the trusted proxy, has processed the request and presented it to the correct service. The proxy's signature base consists of the following: NOTE: '\' line wrapping per RFC 8792 "@path": /foo "@query": ?param=Value&Pet=dog "@method": POST "@authority": service.internal.example "client-cert": :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQ\ KDBJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBD\ QTAeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDM\ FkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXm\ ckC8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQY\ DVR0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8B\ Af8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQ\ GV4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0\ Q6bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: "@signature-params": ("@path" "@query" "@method" "@authority" \ "client-cert");created=1618884473;keyid="test-key-ecc-p256" This results in the following signature: NOTE: '\' line wrapping per RFC 8792 xVMHVpawaAC/0SbHrKRs9i8I3eOs5RtTMGCWXm/9nvZzoHsIg6Mce9315T6xoklyy0y\ zhD9ah4JHRwMLOgmizw== which results in the following signed request sent from the proxy to the internal service with the proxy's signature under the label ttrp: NOTE: '\' line wrapping per RFC 8792 POST /foo?param=Value&Pet=dog HTTP/1.1 Host: service.internal.example Date: Tue, 20 Apr 2021 02:07:55 GMT Content-Type: application/json Content-Length: 18 Client-Cert: :MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQKD\ BJMZXQncyBBdXRoZW50aWNhdGUxGzAZBgNVBAMMEkxBIEludGVybWVkaWF0ZSBDQT\ AeFw0yMDAxMTQyMjU1MzNaFw0yMTAxMjMyMjU1MzNaMA0xCzAJBgNVBAMMAkJDMFk\ wEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8YnXXfaUgmnMtOXU/IncWalRhebrXmck\ C8vdgJ1p5Be5F/3YC8OthxM4+k1M6aEAEFcGzkJiNy6J84y7uzo9M6NyMHAwCQYDV\ R0TBAIwADAfBgNVHSMEGDAWgBRm3WjLa38lbEYCuiCPct0ZaSED2DAOBgNVHQ8BAf\ 8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0RAQH/BBMwEYEPYmRjQGV\ 4YW1wbGUuY29tMAoGCCqGSM49BAMCA0gAMEUCIBHda/r1vaL6G3VliL4/Di6YK0Q6\ bMjeSkC3dFCOOB8TAiEAx/kHSB4urmiZ0NX5r5XarmPk0wmuydBVoU4hBVZ1yhk=: Signature-Input: ttrp=("@path" "@query" "@method" "@authority" \ "client-cert");created=1618884473;keyid="test-key-ecc-p256" Signature: ttrp=:xVMHVpawaAC/0SbHrKRs9i8I3eOs5RtTMGCWXm/9nvZzoHsIg6\ Mce9315T6xoklyy0yzhD9ah4JHRwMLOgmizw==: {"hello": "world"} The internal service can validate the proxy's signature and therefore be able to trust that the client's certificate has been appropriately processed. B.4. HTTP Message Transformations HTTP allows intermediaries and applications to transform an HTTP message without affecting the semantics of the message itself. HTTP message signatures are designed to be robust against many of these transformations in different circumstances. For example, the following HTTP request message has been signed using the Ed25519 algorithm and the key test-key-ed25519: NOTE: '\' line wrapping per RFC 8792 GET /demo?name1=Value1&Name2=value2 HTTP/1.1 Host: example.org Date: Fri, 15 Jul 2022 14:24:55 GMT Accept: application/json Accept: */* Signature-Input: transform=("@method" "@path" "@authority" \ "accept");created=1618884473;keyid="test-key-ed25519" Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: The signature base string for this message is: "@method": GET "@path": /demo "@authority": example.org "accept": application/json, */* "@signature-params": ("@method" "@path" "@authority" "accept")\ ;created=1618884473;keyid="test-key-ed25519" The following message has been altered by adding the Accept-Language header field as well as adding a query parameter. However, since neither the Accept-Language header field nor the query is covered by the signature, the same signature is still valid: NOTE: '\' line wrapping per RFC 8792 GET /demo?name1=Value1&Name2=value2¶m=added HTTP/1.1 Host: example.org Date: Fri, 15 Jul 2022 14:24:55 GMT Accept: application/json Accept: */* Accept-Language: en-US,en;q=0.5 Signature-Input: transform=("@method" "@path" "@authority" \ "accept");created=1618884473;keyid="test-key-ed25519" Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: The following message has been altered by removing the Date header field, adding a Referer header field, and collapsing the Accept header field into a single line. The Date and Referer header fields are not covered by the signature, and the collapsing of the Accept header field is an allowed transformation that is already accounted for by the canonicalization algorithm for HTTP field values. The same signature is still valid: NOTE: '\' line wrapping per RFC 8792 GET /demo?name1=Value1&Name2=value2 HTTP/1.1 Host: example.org Referer: https://developer.example.org/demo Accept: application/json, */* Signature-Input: transform=("@method" "@path" "@authority" \ "accept");created=1618884473;keyid="test-key-ed25519" Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: The following message has been altered by reordering the field values of the original message but not reordering the individual Accept header fields. The same signature is still valid: NOTE: '\' line wrapping per RFC 8792 GET /demo?name1=Value1&Name2=value2 HTTP/1.1 Accept: application/json Accept: */* Date: Fri, 15 Jul 2022 14:24:55 GMT Host: example.org Signature-Input: transform=("@method" "@path" "@authority" \ "accept");created=1618884473;keyid="test-key-ed25519" Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: The following message has been altered by changing the method to POST and the authority to "example.com" (inside the Host header field). Since both the method and authority are covered by the signature, the same signature is NOT still valid: NOTE: '\' line wrapping per RFC 8792 POST /demo?name1=Value1&Name2=value2 HTTP/1.1 Host: example.com Date: Fri, 15 Jul 2022 14:24:55 GMT Accept: application/json Accept: */* Signature-Input: transform=("@method" "@path" "@authority" \ "accept");created=1618884473;keyid="test-key-ed25519" Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: The following message has been altered by changing the order of the two instances of the Accept header field. Since the order of fields with the same name is semantically significant in HTTP, this changes the value used in the signature base, and the same signature is NOT still valid: NOTE: '\' line wrapping per RFC 8792 GET /demo?name1=Value1&Name2=value2 HTTP/1.1 Host: example.org Date: Fri, 15 Jul 2022 14:24:55 GMT Accept: */* Accept: application/json Signature-Input: transform=("@method" "@path" "@authority" \ "accept");created=1618884473;keyid="test-key-ed25519" Signature: transform=:ZT1kooQsEHpZ0I1IjCqtQppOmIqlJPeo7DHR3SoMn0s5J\ Z1eRGS0A+vyYP9t/LXlh5QMFFQ6cpLt2m0pmj3NDA==: Acknowledgements This specification was initially based on [SIGNING-HTTP-MESSAGES]. The editors would like to thank the authors of [SIGNING-HTTP-MESSAGES] -- Mark Cavage and Manu Sporny -- for their work on that Internet-Draft and their continuing contributions. This specification also includes contributions from [SIGNING-HTTP-REQS-OAUTH] and other similar efforts. The editors would also like to thank the following individuals (listed in alphabetical order) for feedback, insight, and implementation of this document and its predecessors: Mark Adamcin, Mark Allen, Paul Annesley, Karl Böhlmark, Stéphane Bortzmeyer, Sarven Capadisli, Liam Dennehy, Stephen Farrell, Phillip Hallam-Baker, Tyler Ham, Eric Holmes, Andrey Kislyuk, Adam Knight, Dave Lehn, Ilari Liusvaara, Dave Longley, James H. Manger, Kathleen Moriarty, Yoav Nir, Mark Nottingham, Adrian Palmer, Lucas Pardue, Roberto Polli, Julian Reschke, Michael Richardson, Wojciech Rygielski, Rich Salz, Adam Scarr, Cory J. Slep, Dirk Stein, Henry Story, Lukasz Szewc, Chris Webber, and Jeffrey Yasskin. Authors' Addresses Annabelle Backman (editor) Amazon P.O. Box 81226 Seattle, WA 98108-1226 United States of America Email: richanna@amazon.com URI: https://www.amazon.com/ Justin Richer (editor) Bespoke Engineering Email: ietf@justin.richer.org URI: https://bspk.io/ Manu Sporny Digital Bazaar 203 Roanoke Street W. Blacksburg, VA 24060 United States of America Email: msporny@digitalbazaar.com