跳到主要内容

2.4. Signing Request Components in a Response Message (在响应消息中对请求组成部分签名)

2.4. Signing Request Components in a Response Message (在响应消息中对请求组成部分签名)

当请求消息产生签名响应消息时, 签名者可以通过向组成部分标识符添加 req 参数, 将请求消息的部分纳入签名基.

req : Boolean 标志, 指示组成部分值派生自触发此响应消息的请求, 而非直接来自响应消息.

此参数可应用于针对请求的 HTTP 字段与派生组成部分, 语义相同. 使用此参数的消息组成部分的组成部分值计算方式与通常相同, 但数据从目标响应消息的相关请求消息拉取, 而非从应用签名的目标响应消息.

注意同一组成部分名称可以带与不带 req 参数同时出现在单个签名基中, 表示来自请求消息与响应消息的同名组成部分.

req 参数可与组成部分标识符的其他适当参数组合, 例如 Dictionary 字段的 key 参数.

例如, 对下列请求提供服务响应时:

注意: 按 RFC 8792 使用 \ 换行

POST /foo?param=Value&Pet=dog HTTP/1.1
Host: example.com
Date: Tue, 20 Apr 2021 02:07:55 GMT
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==:
Content-Type: application/json
Content-Length: 18

{"hello": "world"}

产生下列未签名响应消息:

HTTP/1.1 503 Service Unavailable
Date: Tue, 20 Apr 2021 02:07:56 GMT
Content-Type: application/json
Content-Length: 62
Content-Digest: sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObfwn\
HJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==:

{"busy": true, "message": "Your call is very important to us"}

服务器用自己的密钥签名响应, 在被覆盖组成部分中包含 @status 与若干头字段. 虽然对此应用覆盖了响应的合理部分, 服务器还纳入源自触发此响应的原始请求的若干组成部分. 本例中服务器纳入方法, authority, 路径与请求的 content digest. 请求与响应的 Content-Digest 均纳入响应签名. 对此示例应用, 查询被认为与响应无关故未覆盖. 其他应用会按应用需求做不同决策, 如第 1.4 节讨论.

此示例的签名基为:

"@status": 503
"content-digest": sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObf\
wnHJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==:
"content-type": application/json
"@authority";req: example.com
"@method";req: POST
"@path";req: /foo
"content-digest";req: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A\
2svX+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==:
"@signature-params": ("@status" "content-digest" "content-type" \
"@authority";req "@method";req "@path";req "content-digest";req)\
;created=1618884479;keyid="test-key-ecc-p256"

签名响应消息为:

HTTP/1.1 503 Service Unavailable
Date: Tue, 20 Apr 2021 02:07:56 GMT
Content-Type: application/json
Content-Length: 62
Content-Digest: sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObfwn\
HJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==:
Signature-Input: reqres=("@status" "content-digest" "content-type" \
"@authority";req "@method";req "@path";req "content-digest";req)\
;created=1618884479;keyid="test-key-ecc-p256"
Signature: reqres=:dMT/A/76ehrdBTD/2Xx8QuKV6FoyzEP/I9hdzKN8LQJLNgzU\
4W767HK05rx1i8meNQQgQPgQp8wq2ive3tV5Ag==:

{"busy": true, "message": "Your call is very important to us"}

注意此处使用的 ECDSA 签名算法为非确定性, 即每次运行算法会产生不同签名值. 此处提供的签名值可用给定密钥验证, 但新生成的签名值预计与示例不匹配. 见第 7.3.5 节.

由于请求的组成部分值未在响应消息中重复, 请求者必须将原始消息组成部分值保留足够长时间以验证使用此标识符参数的响应签名. 多数情况下这意味着请求者需要保留原始请求消息, 因为签名者可能根据应用需求在响应中包含请求的任何部分. 由于中间人可能在服务器处理前变更请求消息, 应用必须谨慎不要对此类已变更值签名, 否则客户端将无法验证所得签名.

服务器也可能对签名请求创建签名响应. 对此签名请求示例:

POST /foo?param=Value&Pet=dog HTTP/1.1
Host: example.com
Date: Tue, 20 Apr 2021 02:07:55 GMT
Content-Digest: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A2svX+T\
aPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==:
Content-Type: application/json
Content-Length: 18
Signature-Input: sig1=("@method" "@authority" "@path" "@query" \
"content-digest" "content-type" "content-length")\
;created=1618884475;keyid="test-key-rsa-pss"
Signature: sig1=:e8UJ5wMiRaonlth5ERtE8GIiEH7Akcr493nQ07VPNo6y3qvjdK\
t0fo8VHO8xXDjmtYoatGYBGJVlMfIp06eVMEyNW2I4vN7XDAz7m5v1108vGzaDljr\
d0H8+SJ28g7bzn6h2xeL/8q+qUwahWA/JmC8aOC9iVnwbOKCc0WSrLgWQwTY6VLp4\
2Qt7jjhYT5W7/wCvfK9A1VmHH1lJXsV873Z6hpxesd50PSmO+xaNeYvDLvVdZlhtw\
5PCtUYzKjHqwmaQ6DEuM8udRjYsoNqp2xZKcuCO1nKc0V3RjpqMZLuuyVbHDAbCzr\
0pg2d2VM/OC33JAU7meEjjaNz+d7LWPg==:

{"hello": "world"}

服务器可以选择签名此响应的部分内容, 包括请求的若干部分, 产生下列签名基:

"@status": 503
"content-digest": sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObf\
wnHJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==:
"content-type": application/json
"@authority";req: example.com
"@method";req: POST
"@path";req: /foo
"@query";req: ?param=Value&Pet=dog
"content-digest";req: sha-512=:WZDPaVn/7XgHaAy8pmojAkGWoRx2UFChF41A\
2svX+TaPm+AbwAgBWnrIiYllu7BNNyealdVLvRwEmTHWXvJwew==:
"content-type";req: application/json
"content-length";req: 18
"@signature-params": ("@status" "content-digest" "content-type" \
"@authority";req "@method";req "@path";req "@query";req \
"content-digest";req "content-type";req "content-length";req)\
;created=1618884479;keyid="test-key-ecc-p256"

及下列签名响应:

HTTP/1.1 503 Service Unavailable
Date: Tue, 20 Apr 2021 02:07:56 GMT
Content-Type: application/json
Content-Length: 62
Content-Digest: sha-512=:0Y6iCBzGg5rZtoXS95Ijz03mslf6KAMCloESHObfwn\
HJDbkkWWQz6PhhU9kxsTbARtY2PTBOzq24uJFpHsMuAg==:
Signature-Input: reqres=("@status" "content-digest" "content-type" \
"@authority";req "@method";req "@path";req "@query";req \
"content-digest";req "content-type";req "content-length";req)\
;created=1618884479;keyid="test-key-ecc-p256"
Signature: reqres=:C73J41GVKc+TYXbSobvZf0CmNcptRiWN+NY1Or0A36ISg6ym\
dRN6ZgR2QfrtopFNzqAyv+CeWrMsNbcV2Ojsgg==:

{"busy": true, "message": "Your call is very important to us"}

注意此处 ECDSA 为非确定性. 见第 7.3.5 节.

对签名请求的响应进行签名的应用应签名请求签名值的全部组成部分, 以提供充分覆盖并防护第 7.3.7 节讨论的一类碰撞攻击. 本例服务器除响应组成部分外, 已将客户端请求上 Signature-Input 字段所列全部组成部分纳入响应签名.

虽然在语法上可以将请求消息的 SignatureSignature-Input 字段纳入使用此机制的响应的签名组成部分, 不建议这样做. 因为对签名的签名并不像预期那样对被覆盖组成部分提供传递性覆盖, 且该实践易受第 7.3.7 节讨论的若干攻击. 需要信号表示成功处理或接收签名的应用需要仔细规定安全发送此类信号的替代机制.

使用此标志时, 响应签名仅能覆盖请求中包含的内容. 因此, 若应用需要在响应签名下包含请求的消息内容, 客户端需要纳入覆盖该内容的手段, 例如 Content-Digest 字段. 更多信息见第 7.2.8 节讨论.

req 参数不得用于针对请求消息的签名中的任何组成部分.