

# 尾随标头的签名计算（分块上传）（Amazon 签名版本 4）
<a name="sigv4-streaming-trailers"></a>

使用 `Authorization` 标头对请求进行身份验证时，您也可以分块上传有效载荷。当您以分块发送对象的数据时，您也可以选择包括尾随标头。（有关更多信息，请参阅 [Authorization 标头的签名计算：在多个分块中传输有效载荷（分块上传）（Amazon 签名版本 4）](sigv4-streaming.md)。） 本节介绍当您想在多分块上传的末尾包含尾随标头时需要采取的步骤。

 

**重要**  
当包含尾随标头时，必须在初始标头中发送以下内容：  
您必须将 `x-amz-content-sha256` 设置为适当的值，以表示将包含尾部。要查看 `x-amz-content-sha256` 的可接受值，请参阅[对请求进行身份验证：使用 Authorization 标头（Amazon 签名版本 4）](sigv4-auth-using-authorization-header.md)。
您必须设置 `x-amz-trailer`，才能在尾随标头中指明要包含的内容。

 只有在上传分块后才会发送尾随标头。之前的分块按常规发送，并按照前几节所述进行签名，包括发送有效载荷为 0 字节的最后一个分块。尾随标头作为其自己的分块包含在内，并在有效载荷为 0 字节的最后一个分块之后发送。例如，如果您的数据以 100 KB 的分块结尾，则应发送以下内容：
+ 之前的数据分块
+ 对象的 100 KB 的最后一个分块
+ 0 字节的分块，表示对象的结尾
+ 尾随标头分块

## 示例：检查签名计算
<a name="example-signature-calculations-trailing-header"></a>

您可以将本节中的示例用作参考，以检查代码中的签名计算。在查看示例之前，请注意以下事项：

 
+  这些示例中的签名计算使用以下示例安全凭证。    
[See the AWS documentation website for more details](http://docs.amazonaws.cn/AmazonS3/latest/developerguide/sigv4-streaming-trailers.html)
+ 所有示例都使用请求时间戳 20130524T000000Z (`Fri, 24 May 2013 00:00:00 GMT`)。
+ 所有示例都使用 `examplebucket` 作为存储桶名称。
+ 假设存储桶位于美国东部（弗吉尼亚州北部）区域，凭证 `Scope` 和 `Signing Key` 计算使用 `us-east-1` 作为区域说明符。有关更多信息，请参阅 *Amazon Web Services 一般参考* 中的[区域和终端节点](https://docs.amazonaws.cn/general/latest/gr/rande.html#s3_region)。
+ 您可以使用路径类型请求或虚拟托管类型请求。以下示例使用虚拟托管类型请求，例如：

  ```
  https://examplebucket.s3.amazonaws.com/photos/photo1.jpg
  ```

  有关更多信息，请参阅《Amazon Simple Storage Service 用户指南》**中的[存储桶的虚拟托管](https://docs.amazonaws.cn/AmazonS3/latest/userguide/VirtualHosting.html)。

以下示例发送 `PUT` 请求以上传对象。签名计算假设如下：

 
+ 您正在上传一个 65 KB 的文本文件，文件内容是由字母“a”组成的单字符的字符串。
+ 分块大小为 64 KB。因此，有效载荷分三个分块上传，分别为 64 KB、1 KB，以及包含 0 字节分块数据的最后一个分块。
+ 生成的对象具有键名称 `chunkObject.txt`。
+ 您正在通过添加 `x-amz-storage-class` 请求标头来请求 `REDUCED_REDUNDANCY` 作为存储类别。
+ 传输包含 CRC32C 校验和值作为尾随标头。

有关 API 操作的信息，请参阅 [PutObject](https://docs.amazonaws.cn/AmazonS3/latest/API/API_PutObject.html)。常用请求语法如下：

```
PUT /examplebucket/chunkObject.txt HTTP/1.1
Host: s3.amazonaws.com
x-amz-date: 20130524T000000Z 
x-amz-storage-class: REDUCED_REDUNDANCY
Authorization: {{SignatureToBeCalculated}}
x-amz-content-sha256: STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILER
Content-Encoding: aws-chunked
x-amz-decoded-content-length: 66560
x-amz-trailer: x-amz-checksum-crc32c
Content-Length: 66946
{{<Payload>}}
```



以下步骤显示了签名计算。

1. 

**种子签名：创建待签字符串**

   1. 

**CanonicalRequest**

       

      ```
      PUT
      /examplebucket/chunkObject.txt
      
      content-encoding:aws-chunked
      host:s3.amazonaws.com
      x-amz-content-sha256:STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILER
      x-amz-date:20130524T000000Z
      x-amz-decoded-content-length:66560
      x-amz-storage-class:REDUCED_REDUNDANCY
      x-amz-trailer:x-amz-checksum-crc32c
      
      content-encoding;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class;x-amz-trailer
      STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILER
      ```

      在规范请求中，第三行是空的，因为请求中没有查询参数。最后一行是作为经过哈希处理的有效载荷值提供的常量字符串，应与 `x-amz-content-sha256 header` 的值相同。

   1. 

**StringToSign**

       

      ```
      AWS4-HMAC-SHA256
      20130524T000000Z
      20130524/us-east-1/s3/aws4_request
      44d48b8c2f70eae815a0198cc73d7a546a73a93359c070abbaa5e6c7de112559
      ```

       

       
**注意**  
有关待签字符串中每行的信息，请参阅解释种子签名计算的图表。

1. 

**SigningKey**

    

   ```
   signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "{{<YourSecretAccessKey>}}","20130524"),"us-east-1"),"s3"),"aws4_request")						
   ```

    

1. 

**种子签名**

    

   ```
   106e2a8a18243abcf37539882f36619c00e2dfc72633413f02d3b74544bfeb8e
   ```

    

1. 

**Authorization 标头**

   生成的 Authorization 标头如下：

    

   ```
   AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class,Signature=106e2a8a18243abcf37539882f36619c00e2dfc72633413f02d3b74544bfeb8e
   ```

    

1. 

**分块 1：（65536 字节，字母“a”的值为 97）**

   1. 分块待签字符串：

      ```
      AWS4-HMAC-SHA256-PAYLOAD
      20130524T000000Z
      20130524/us-east-1/s3/aws4_request
      106e2a8a18243abcf37539882f36619c00e2dfc72633413f02d3b74544bfeb8e
      e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      bf718b6f653bebc184e1479f1935b8da974d701b893afcf49e701f3e2f9f9c5a
      ```

       
**注意**  
有关待签字符串中每行的信息，请参阅前一主题（[计算种子签名](sigv4-streaming.md#sigv4-chunked-upload-sig-calculation-chunk0)）中的图表，其中显示了待签字符串的各个组成部分。例如，最后三行包括以下内容：  
{{previous-signature}}
`hash("")`
`hash({{current-chunk-data}})`

   1. 分块签名：

      ```
      b474d8862b1487a5145d686f57f013e54db672cee1c953b3010fb58501ef5aa2
      ```

   1. 发送的分块数据：

      ```
      10000;chunk-signature=b474d8862b1487a5145d686f57f013e54db672cee1c953b3010fb58501ef5aa2
      <65536-bytes>
      ```

1. 

**分块 2：（1024 字节，字母“a”的值为 97）**

   1. 分块待签字符串：

      ```
      AWS4-HMAC-SHA256-PAYLOAD
      20130524T000000Z
      20130524/us-east-1/s3/aws4_request
      b474d8862b1487a5145d686f57f013e54db672cee1c953b3010fb58501ef5aa2
      e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      2edc986847e209b4016e141a6dc8716d3207350f416969382d431539bf292e4a
      ```

   1. 分块签名：

      ```
      1c1344b170168f8e65b41376b44b20fe354e373826ccbbe2c1d40a8cae51e5c7
      ```

   1. 发送的分块数据：

      ```
      400;chunk-signature=1c1344b170168f8e65b41376b44b20fe354e373826ccbbe2c1d40a8cae51e5c7
      <1024-bytes>
      ```

1. 

**分块 3：（0 字节数据）**

   1. 分块待签字符串：

      ```
      AWS4-HMAC-SHA256-PAYLOAD
      20130524T000000Z
      20130524/us-east-1/s3/aws4_request
      1c1344b170168f8e65b41376b44b20fe354e373826ccbbe2c1d40a8cae51e5c7
      e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      ```

   1. 分块签名：

      ```
      2ca2aba2005185cf7159c6277faf83795951dd77a3a99e6e65d5c9f85863f992
      ```

   1. 发送的分块数据：

      ```
      0;chunk-signature=2ca2aba2005185cf7159c6277faf83795951dd77a3a99e6e65d5c9f85863f992
      ```

1. 

**分块 4：尾随标头**

   1. 尾部分块待签字符串：

      ```
      AWS4-HMAC-SHA256-TRAILER
      20130524T000000Z
      20130524/us-east-1/s3/aws4_request
      2ca2aba2005185cf7159c6277faf83795951dd77a3a99e6e65d5c9f85863f992
      1e376db7e1a34a8ef1c4bcee131a2d60a1cb62503747488624e10995f448d774
      ```
**注意**  
最后两行是 `previous-signature`（0 字节的数据分块签名）、`hash`（{{trailing-checksum-header-name}}:{{base64-encoded-trailing-checksum-value}}\\n）。  
计算哈希值的方式如下，不带空格：  
尾随校验和标头名称
冒号 (`:`)
Base64 编码的尾随校验和值
换行符 (`\n`)。
在此示例中，我们使用 `crc32c` 哈希算法，base64 编码的校验和值为 `sOO8/Q==`，可以按如下方式表示计算：`hash('x-amz-checksum-crc32c:sOO8/Q==\n')`。

   1. 分块签名：

      ```
      d81f82fc3505edab99d459891051a732e8730629a2e4a59689829ca17fe2e435
      ```

   1. 发送的分块数据：

      ```
      x-amz-checksum-crc32c:sOO8/Q==
      x-amz-trailer-signature:d81f82fc3505edab99d459891051a732e8730629a2e4a59689829ca17fe2e435
      ```