Skip to main content

4.3. Multiple Signatures

4.3. Multiple Signatures

Multiple distinct signatures MAY be included in a single message. Each distinct signature MUST have a unique label. These multiple signatures could all be added by the same signer, or they could come from several different signers. For example, a signer may include multiple signatures signing the same message components with different keys or algorithms to support verifiers with different capabilities, or a reverse proxy may include information about the client in fields when forwarding the request to a service host, including a signature over the client's original signature values.

The following non-normative example starts with a signed request from the client. A reverse proxy takes this request and validates the client's signature:

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-Length: 18 Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: Signature-Input: sig1=("@method" "@authority" "@path"
"content-digest" "content-type" "content-length")
;created=1618884475;keyid="test-key-ecc-p256" Signature: sig1=:X5spyd6CFnAG5QnDyHfqoSNICd+BUP4LYMz2Q0JXlb//4Ijpzp
+kve2w4NIyqeAuM7jTDX+sNalzA8ESSaHD3A==:

{"hello": "world"}

The proxy then alters the message before forwarding it on to the origin server, changing the target host and adding the Forwarded header field defined in [RFC7239]:

NOTE: '' line wrapping per RFC 8792

POST /foo?param=Value&Pet=dog HTTP/1.1 Host: origin.host.internal.example Date: Tue, 20 Apr 2021 02:07:56 GMT Content-Type: application/json Content-Length: 18 Forwarded: for=192.0.2.123;host=example.com;proto=https Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: Signature-Input: sig1=("@method" "@authority" "@path"
"content-digest" "content-type" "content-length")
;created=1618884475;keyid="test-key-ecc-p256" Signature: sig1=:X5spyd6CFnAG5QnDyHfqoSNICd+BUP4LYMz2Q0JXlb//4Ijpzp
+kve2w4NIyqeAuM7jTDX+sNalzA8ESSaHD3A==:

{"hello": "world"}

The proxy is in a position to validate the incoming client's signature and make its own statement to the origin server about the nature of the request that it is forwarding by adding its own signature over the new message before passing it along to the origin server. The proxy also includes all the elements from the original message that are relevant to the origin server's processing. In many cases, the proxy will want to cover all the same components that were covered by the client's signature, which is the case in the following example. Note that in this example, the proxy is signing over the new authority value, which it has changed. The proxy also adds the Forwarded header field to its own signature value. The proxy identifies its own key and algorithm and, in this example, includes an expiration for the signature to indicate to downstream systems that the proxy will not vouch for this signed message past this short time window. This results in a signature base of:

NOTE: '' line wrapping per RFC 8792

"@method": POST "@authority": origin.host.internal.example "@path": /foo "content-digest": sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX
+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: "content-type": application/json "content-length": 18 "forwarded": for=192.0.2.123;host=example.com;proto=https "@signature-params": ("@method" "@authority" "@path"
"content-digest" "content-type" "content-length" "forwarded")
;created=1618884480;keyid="test-key-rsa";alg="rsa-v1_5-sha256"
;expires=1618884540

and a signature output value of:

NOTE: '' line wrapping per RFC 8792

S6ZzPXSdAMOPjN/6KXfXWNO/f7V6cHm7BXYUh3YD/fRad4BCaRZxP+JH+8XY1I6+8Cy
+CM5g92iHgxtRPz+MjniOaYmdkDcnL9cCpXJleXsOckpURl49GwiyUpZ10KHgOEe11s
x3G2gxI8S0jnxQB+Pu68U9vVcasqOWAEObtNKKZd8tSFu7LB5YAv0RAGhB8tmpv7sFn
Im9y+7X5kXQfi8NMaZaA8i2ZHwpBdg7a6CMfwnnrtflzvZdXAsD3LH2TwevU+/PBPv0
B6NMNk93wUs/vfJvye+YuI87HU38lZHowtznbLVdp770I6VHR6WfgS9ddzirrswsE1w
5o0LV/g==

These values are added to the HTTP request message by the proxy. The original signature is included under the label sig1, and the reverse proxy's signature is included under the label proxy_sig. The proxy uses the key test-key-rsa to create its signature using the rsa- v1_5-sha256 signature algorithm, while the client's original signature was made using the key test-key-rsa-pss and an RSA-PSS signature algorithm:

NOTE: '' line wrapping per RFC 8792

POST /foo?param=Value&Pet=dog HTTP/1.1 Host: origin.host.internal.example Date: Tue, 20 Apr 2021 02:07:56 GMT Content-Type: application/json Content-Length: 18 Forwarded: for=192.0.2.123;host=example.com;proto=https Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==: Signature-Input: sig1=("@method" "@authority" "@path"
"content-digest" "content-type" "content-length")
;created=1618884475;keyid="test-key-ecc-p256",
proxy_sig=("@method" "@authority" "@path" "content-digest"
"content-type" "content-length" "forwarded")
;created=1618884480;keyid="test-key-rsa";alg="rsa-v1_5-sha256"
;expires=1618884540 Signature: sig1=:X5spyd6CFnAG5QnDyHfqoSNICd+BUP4LYMz2Q0JXlb//4Ijpzp
+kve2w4NIyqeAuM7jTDX+sNalzA8ESSaHD3A==:,
proxy_sig=:S6ZzPXSdAMOPjN/6KXfXWNO/f7V6cHm7BXYUh3YD/fRad4BCaRZxP+
JH+8XY1I6+8Cy+CM5g92iHgxtRPz+MjniOaYmdkDcnL9cCpXJleXsOckpURl49G
wiyUpZ10KHgOEe11sx3G2gxI8S0jnxQB+Pu68U9vVcasqOWAEObtNKKZd8tSFu7
LB5YAv0RAGhB8tmpv7sFnIm9y+7X5kXQfi8NMaZaA8i2ZHwpBdg7a6CMfwnnrtf
lzvZdXAsD3LH2TwevU+/PBPv0B6NMNk93wUs/vfJvye+YuI87HU38lZHowtznbL
Vdp770I6VHR6WfgS9ddzirrswsE1w5o0LV/g==:

{"hello": "world"}

While the proxy could additionally include the client's Signature field value and Signature-Input fields from the original message in the new signature's covered components, this practice is NOT RECOMMENDED due to known weaknesses in signing signature values as discussed in Section 7.3.7. The proxy is in a position to validate the client's signature; the changes the proxy makes to the message will invalidate the existing signature when the message is seen by the origin server. In this example, it is possible for the origin server to have additional information in its signature context to account for the change in authority, though this practice requires additional configuration and extra care as discussed in Section 7.4.4. In other applications, the origin server will not be able to verify the original signature itself but will still want to verify that the proxy has done the appropriate validation of the client's signature. An application that needs to signal successful processing or receipt of a signature would need to carefully specify alternative mechanisms for sending such a signal securely.