

# Authorization 标头的签名计算：在单个分块中传输有效载荷（Amazon 签名版本 4）
<a name="sig-v4-header-based-auth"></a>

使用 `Authorization` 标头对请求进行身份验证时，标头值包括签名等其它内容。签名计算因您就传输有效载荷所进行的选择而异（[概述](sigv4-auth-using-authorization-header.md#sigv4-auth-header-overview)）。本节介绍在选择以单个分块传输有效载荷时的签名计算。示例部分（请参阅[示例：签名计算](#example-signature-calculations)）显示了签名计算和生成的 `Authorization` 标头，您可以将其用作测试套件来验证代码。

**重要**  
在单个分块中传输有效载荷时，您可以选择在签名计算中包含有效载荷哈希值，称为*已签名的有效载荷*（如果不包括该哈希值，则该有效载荷被视为*未签名*）。下一节中讨论的签名过程适用于这两者，但请注意以下区别：  
   
**签名的有效载荷选项**：在构造规范请求时包含有效载荷哈希值（然后，该哈希值将成为 StringToSign 的一部分，如签名计算部分所述）。在向 S3 发送请求时，您还可以指定与 `x-amz-content-sha256` 标头值相同的值。
**未签名的有效载荷选项**：您在构造规范请求时包含文本字符串 `UNSIGNED-PAYLOAD`，并在向 Amazon S3 发送请求时设置与 `x-amz-content-sha256` 标头值相同的值。
当您将请求发送到 Amazon S3 时，`x-amz-content-sha256` 标头值会通知 Amazon S3 有效载荷是否已签名。然后，Amazon S3 可以相应地创建签名以进行验证。  
在这两种情况下，由于 `x-amz-content-sha256` 标头值已经是 `HashedPayload` 的一部分，因此您无需将 `x-amz-content-sha256` 标头作为规范标头包含在内。

## 计算签名
<a name="create-signature-presign-entire-payload"></a>

要计算签名，首先需要一个待签字符串。然后，使用签名密钥计算待签字符串的 `HMAC-SHA256` 哈希值。下图演示了该过程，包括您为签名而创建的字符串的各个组成部分 

Amazon S3 收到经身份验证的请求时，它将计算签名，然后将其与您在请求中提供的签名进行比较。出于此原因，您必须采用 Amazon S3 使用的相同方法来计算签名。根据适用于签名的统一格式放置请求的过程称为标准化。

 

![AWS4-HMAC-SHA256 签名流程图，显示了规范请求、StringToSign 和签名步骤。](http://docs.amazonaws.cn/AmazonS3/latest/developerguide/images/sigV4-using-auth-header.png)


下表介绍了图中显示的函数。您需要为这些函数实现代码。


| 函数 | 说明 | 
| --- | --- | 
| Lowercase() | 将字符串转换为小写。 | 
| Hex() | base-16 编码的小写形式。 | 
| SHA256Hash() | 安全哈希算法（SHA）加密哈希函数。 | 
| HMAC-SHA256() | 使用 SHA256 算法和提供的签名密钥计算 HMAC。这是最终的签名。 | 
| Trim() | 删除所有前导空格或尾随空格。 | 
| UriEncode() | URI 对每个字节进行编码。UriEncode() 必须强制执行以下规则：+  URI 对除非预留字符之外的所有字节进行编码：“A”-“Z”、“a”-“z”、“0”-“9”、“-”、“.”、“\_”和“\~”。 <br />+ 空格字符是预留字符，必须编码为“%20”（而不是“\+”）。<br />+ 每个 URI 编码字节由“%”和该字节的两位十六进制值组成。<br />+ 十六进制值中的字母必须为大写，例如“%1A”。<br />+ 对除对象键名称之外的所有位置的正斜杠字符“/”进行编码。例如，如果对象键名称是 `photos/Jan/sample.jpg`，则不会对键名称中的正斜杠进行编码。 由于底层 RFC 中的实现差异和相关歧义，您开发平台提供的标准 UrienCode 函数可能无法正常工作。建议您编写自己的自定义 UrienCode 函数，以确保编码能够正常工作。 <br />以下是 Java 中的 UriEncode() 函数示例。<pre>public static String UriEncode(CharSequence input, boolean encodeSlash) {<br />          StringBuilder result = new StringBuilder();<br />          for (int i = 0; i < input.length(); i++) {<br />              char ch = input.charAt(i);<br />              if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '-' || ch == '~' || ch == '.') {<br />                  result.append(ch);<br />              } else if (ch == '/') {<br />                  result.append(encodeSlash ? "%2F" : ch);<br />              } else {<br />                  result.append(toHexUTF8(ch));<br />              }<br />          }<br />          return result.toString();<br />      }</pre> | 

### 任务 1：创建规范请求
<a name="canonical-request"></a>

本节提供创建规范请求的概述。

以下是 Amazon S3 用来计算签名的规范请求格式。要使签名匹配，您必须使用以下格式创建规范请求：

 

```
{{<HTTPMethod>}}\n
{{<CanonicalURI>}}\n
{{<CanonicalQueryString>}}\n
{{<CanonicalHeaders>}}\n
{{<SignedHeaders>}}\n
{{<HashedPayload>}}
```

其中：

 
+ {{HTTPMethod}} 是 HTTP 方法之一，例如 GET、PUT、HEAD 和 DELETE。
+ {{CanonicalURI}} 是 URI 的绝对路径组件的 URI 编码版本，即从域名后面的“/”开始，直至字符串结尾处的任何内容；或者如果包含查询字符串参数，则为直至问号字符（“?”）的任何内容。以下示例中的 URI `/examplebucket/myphoto.jpg` 是绝对路径，并且您无需在绝对路径中对“/”进行编码：

   

  ```
  http://s3.amazonaws.com/examplebucket/myphoto.jpg
  ```

   
**注意**  
向 Amazon S3 发出请求时，您没有对 URI 路径进行规范化。例如，您可能有一个存储桶，其中包含一个名为“my-object//example//photo.user”的对象。对路径进行规范化会将请求中的对象名称更改为“my-object/example/photo.user”。这是该对象的不正确路径。
+ {{CanonicalQueryString}} 指定 URI 编码的查询字符串参数。您可以单独对名称和值进行 URI 编码。您还必须按键名称的字母顺序对规范查询字符串中的参数进行排序。编码后进行排序。以下 URI 示例中的查询字符串是：`prefix=somePrefix&marker=someMarker&max-keys=20`

   

  ```
  http://s3.amazonaws.com/examplebucket?prefix=somePrefix&marker=someMarker&max-keys=20
  ```

  规范查询字符串如下所示（为便于阅读，此示例中添加了换行符：）：

   

  ```
  UriEncode("marker")+"="+UriEncode("someMarker")+"&"+
  UriEncode("max-keys")+"="+UriEncode("20") + "&" +
  UriEncode("prefix")+"="+UriEncode("somePrefix")
  ```

  当请求针对子资源时，相应的查询参数值将为空字符串（“”）。例如，以下 URI 标识了 `examplebucket` 存储桶上的 `ACL` 子资源：

   

  ```
  http://s3.amazonaws.com/examplebucket?acl 
  ```

  本例中的 CanonicalQueryString 如下：

   

  ```
  UriEncode("acl") + "=" + ""
  ```

  如果 URI 不包含“?”，则请求中没有查询字符串，并且您需要将规范查询字符串设置为空字符串（“”）。此外，仍需包含“\\n”。
+ {{CanonicalHeaders}} 是请求标头及其值的列表。各个标头名称和值对用换行符（“\\n”）分隔。标头名称必须为小写。您必须按字母顺序对标头名称进行排序才能构造字符串，如以下示例所示：

   

  ```
  Lowercase({{<HeaderName1>}})+":"+Trim({{<value>}})+"\n"
  Lowercase({{<HeaderName2>}})+":"+Trim({{<value>}})+"\n"
  ...
  Lowercase({{<HeaderNameN>}})+":"+Trim({{<value>}})+"\n"
  ```

  上一部分介绍了本示例中使用的 `Lowercase()` 和 `Trim()` 函数。

  {{CanonicalHeaders}} 列表必须包含以下内容：
  + HTTP `host` 标头。
  + 如果请求中存在 `Content-MD5` 标头，则必须将其添加到 {{CanonicalHeaders}} 列表中。
  + 此外，还必须添加计划在请求中包含的所有 `x-amz-*` 标头。例如，如果您使用临时安全凭证，则请求中必须包含 `x-amz-security-token`。您必须将此标头添加到 {{CanonicalHeaders}} 列表中。
**注意**  
所有 Amazon 签名版本 4 请求都需要 `x-amz-content-sha256` 标头。它将提供请求负载的哈希。但是，您无需将 `x-amz-content-sha256` 作为规范标头包含在内，因为 S3 在计算请求中发送的有效载荷哈希值时会自动使用其值。
如果不包含有效负载，则必须提供空字符串的哈希值。
如果您不希望 S3 检查请求的哈希值，则可以改用文本字符串 `"UNSIGNED-PAYLOAD"`。

  以下是示例 `CanonicalHeaders` 字符串。标头名称为小写且已排序。  
**Example 示例 1**  

  ```
  host:s3.amazonaws.com
  x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
  x-amz-date:20130708T220855Z
  ```  
**Example 示例 2**  

  ```
  host:s3.amazonaws.com
  x-amz-content-sha256:UNSIGNED-PAYLOAD
  x-amz-date:20130708T220855Z
  ```  
**Example 示例 3**  

  ```
  host:s3.amazonaws.com
  x-amz-date:20130708T220855Z
  ```
**注意**  
为了计算授权签名，需要主机标头和所有 `x-amz-*` 标头（不包括 `x-amz-content-sha256`）。但是，为了防止篡改数据，您应该考虑在签名计算中包含所有标头。  
对 `x-amz-content-sha256` 标头进行签名是可选的，因为 S3 将在计算收到的请求有效载荷哈希值时使用其值。
+ {{SignedHeaders}} 是按字母顺序排序、以分号分隔的小写请求标头名称的列表。列表中的请求标头与您在 `CanonicalHeaders` 字符串中包含的标头相同。在前面的示例中，{{SignedHeaders}} 的值如下：

    
**Example 示例 1 和 2**  

  ```
  host;x-amz-content-sha256;x-amz-date
  ```  
**Example 示例 3**  

  ```
  host;x-amz-date
  ```
+ {{HashedPayload}} 是请求有效载荷的 SHA256 哈希值的十六进制值。

   

  ```
  Hex(SHA256Hash({{<payload>}})
  ```

  如果请求中不包含有效负载，则按如下方式计算空字符串的哈希值：

   

  ```
  Hex(SHA256Hash(""))
  ```

  哈希值将返回以下值：

   

  ```
  e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  
  ```

  例如，当您使用 PUT 请求上传对象时，您需要在正文中提供对象数据。当您使用 GET 请求检索对象时，您将计算空字符串哈希值。

### 任务 2：创建待签字符串
<a name="request-string"></a>

本节提供创建待签字符串的概述。有关分步说明，请参阅《Amazon Web Services 一般参考》**中的[任务 2：创建待签字符串](https://docs.amazonaws.cn/general/latest/gr/sigv4-create-string-to-sign.html)。

待签字符串是以下字符串的结合：

 

```
"AWS4-HMAC-SHA256" + "\n" +
timeStampISO8601Format + "\n" +
{{<Scope>}} + "\n" +
Hex(SHA256Hash({{<CanonicalRequest>}}))
```

常量字符串 `AWS4-HMAC-SHA256` 指定您正在使用的哈希算法 HMAC-SHA256。`timeStamp` 是采用 ISO 8601 格式的当前 UTC 时间（例如 `20130524T000000Z`）。

`Scope` 将生成的签名绑定到特定的日期、Amazon Web Services 区域和服务。这样，生成的签名将仅在特定区域和特定服务中有效。签名在指定日期后的七天内有效。

 

```
date.Format({{<YYYYMMDD>}}) + "/" + {{<region>}} + "/" + {{<service>}} + "/aws4_request"
```

 对于 Amazon S3，服务字符串为 `s3`。有关 {{region}} 字符串的列表，请参阅《Amazon Web Services 一般参考》**中的[区域和端点](https://docs.amazonaws.cn/general/latest/gr/rande.html#s3_region)。此表中的“区域”列提供了有效区域字符串的列表。

 以下范围将生成的签名限制为 `us-east-1` 区域和 Amazon S3。

```
20130606/us-east-1/s3/aws4_request
```

 

**注意**  
 `Scope` 必须使用与用于计算签名密钥的相同日期，如下一节所述。

### 任务 3：计算签名
<a name="signing-key"></a>

 在 Amazon 签名版本 4 中，您首先创建一个范围仅限于特定区域和服务的签名密钥，而不是使用 Amazon 访问密钥对请求进行签名。 有关签名密钥的更多信息，请参阅[对请求进行签名简介](sig-v4-authenticating-requests.md#signing-request-intro)。

 

```
DateKey              = HMAC-SHA256("AWS4"+"{{<SecretAccessKey>}}", "{{<YYYYMMDD>}}")
DateRegionKey        = HMAC-SHA256({{<DateKey>}}, "{{<aws-region>}}")
DateRegionServiceKey = HMAC-SHA256({{<DateRegionKey>}}, "{{<aws-service>}}")
SigningKey           = HMAC-SHA256({{<DateRegionServiceKey>}}, "aws4_request")
```

 

**注意**  
一些使用案例可以处理签名密钥长达 7 天。有关更多信息，请参阅[与他人共享对象](https://docs.amazonaws.cn/AmazonS3/latest/dev/ShareObjectPreSignedURL.html)。

有关区域字符串的列表，请参阅《Amazon Web Services 一般参考》**中的[区域和端点](https://docs.amazonaws.cn/general/latest/gr/rande.html#s3_region)。

 使用签名密钥，您可以将 Amazon 凭证保存在一个安全的地方。例如，如果您有多个服务器与 Amazon S3 通信，则可以与这些服务器共享签名密钥；您不必在每个服务器上保留秘密访问密钥的副本。签名密钥的有效期最长为七天。因此，每次计算签名密钥时，都需要与服务器共享签名密钥。有关更多信息，请参阅 [对请求进行身份验证（Amazon 签名版本 4）](sig-v4-authenticating-requests.md)。

最终签名是待签字符串的 HMAC-SHA256 哈希值，使用签名密钥作为密钥。

 

```
HMAC-SHA256(SigningKey, StringToSign)
```

有关创建签名的分步说明，请参阅《Amazon Web Services 一般参考》**中的[任务 3：创建签名](https://docs.amazonaws.cn/general/latest/gr/sigv4-calculate-signature.html)。

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

您可以将本节中的示例用作参考，以检查代码中的签名计算。示例中显示的计算使用以下数据：

 
+  访问密钥示例。    
[See the AWS documentation website for more details](http://docs.amazonaws.cn/AmazonS3/latest/developerguide/sig-v4-header-based-auth.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)。

#### 示例：GET 对象
<a name="example-signature-GET-object"></a>

以下示例从 `examplebucket` 获取对象（test.txt）的前 10 个字节。有关 API 操作的更多信息，请参阅 [GetObject](https://docs.amazonaws.cn/AmazonS3/latest/API/API_GetObject.html)。

 

```
GET /test.txt HTTP/1.1
Host: examplebucket.s3.amazonaws.com
Authorization: {{SignatureToBeCalculated}}
Range: bytes=0-9 
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date: 20130524T000000Z
```

由于此 GET 请求不提供任何正文内容，因此 `x-amz-content-sha256` 值可以是空请求正文的哈希值，也可以是文本字符串 `"UNSIGNED-PAYLOAD"`。以下步骤显示使用空字符串的哈希值进行签名计算以及构造 `Authorization` 标头的过程。

1. 

**StringToSign**

   1. 

**CanonicalRequest**

       

      ```
      GET
      /test.txt
      
      host:examplebucket.s3.amazonaws.com
      range:bytes=0-9
      x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      x-amz-date:20130524T000000Z
      
      host;range;x-amz-content-sha256;x-amz-date
      e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      ```

      在规范请求字符串中，最后一行是空请求正文的哈希值。因为请求中没有查询参数，所以第三行是空的。

   1. 

**StringToSign**

       

      ```
      AWS4-HMAC-SHA256
      20130524T000000Z
      20130524/us-east-1/s3/aws4_request
      7344ae5b7ee6c3e7e6b0fe0640412a37625d1fbfff95c48bbb2dc43964946972
      ```

       

1. 

**SigningKey**

    

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

    

1. 

**Signature**

    

   ```
   f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41
   ```

    

1. 

**Authorization 标头**

   生成的 `Authorization` 标头如下：

    

   ```
   AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-content-sha256;x-amz-date,Signature=f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41
   ```

    

#### 示例：PUT 对象
<a name="example-signature-PUT-object"></a>

此示例 PUT 请求在 `examplebucket` 中创建一个对象 (`test$file.text`)。示例假定以下各项：

 
+ 您正在通过添加 `x-amz-storage-class` 请求标头来请求 `REDUCED_REDUNDANCY` 作为存储类别。有关存储类别的信息，请参阅《Amazon Simple Storage Service 用户指南》**中的[存储类别](https://docs.amazonaws.cn/AmazonS3/latest/userguide/UsingMetadata.html#storage-class-intro)。
+ 已上传文件的内容是一个字符串 `"Welcome to Amazon S3."`，请求中 `x-amz-content-sha256` 的值基于这个字符串。

有关 API 操作的信息，请参阅 [PutObject](https://docs.amazonaws.cn/AmazonS3/latest/API/API_PutObject.html)。

```
PUT test$file.text HTTP/1.1
Host: examplebucket.s3.amazonaws.com
Date: Fri, 24 May 2013 00:00:00 GMT
Authorization: {{SignatureToBeCalculated}}
x-amz-date: 20130524T000000Z 
x-amz-storage-class: REDUCED_REDUNDANCY
x-amz-content-sha256: 44ce7dd67c959e0d3524ffac1771dfbba87d2b6b4b4e99e42034a8b803f8b072

{{<Payload>}}
```



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

1. 

**StringToSign**

   1. 

**CanonicalRequest**

       

      ```
      PUT
      /test%24file.text
      
      date:Fri, 24 May 2013 00:00:00 GMT
      host:examplebucket.s3.amazonaws.com
      x-amz-content-sha256:44ce7dd67c959e0d3524ffac1771dfbba87d2b6b4b4e99e42034a8b803f8b072
      x-amz-date:20130524T000000Z
      x-amz-storage-class:REDUCED_REDUNDANCY
      
      date;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class
      44ce7dd67c959e0d3524ffac1771dfbba87d2b6b4b4e99e42034a8b803f8b072
      ```

      在规范请求中，第三行是空的，因为请求中没有查询参数。可以选择对 `x-amz-content-sha256` 规范标头进行签名，因为其有效载荷哈希值已在请求的底部提供。最后一行是正文的哈希值，它应该与在 HTTP 请求中发送给 S3 的 `x-amz-content-sha256 header` 值相同。

   1. 

**StringToSign**

       

      ```
      AWS4-HMAC-SHA256
      20130524T000000Z
      20130524/us-east-1/s3/aws4_request
      9e0e90d9c76de8fa5b200d8c849cd5b8dc7a3be3951ddb7f6a76b4158342019d
      ```

       

1. 

**SigningKey**

    

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

    

1. 

**Signature**

    

   ```
   98ad721746da40c64f1a55b78f14c238d841ea1380cd77a1b5971af0ece108bd
   ```

    

1. 

**Authorization 标头**

   生成的 `Authorization` 标头如下：

    

   ```
   AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=date;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class,Signature=98ad721746da40c64f1a55b78f14c238d841ea1380cd77a1b5971af0ece108bd
   ```

    

#### 示例：GET 存储桶生命周期
<a name="example-signature-GET-bucket-lifecycle"></a>

以下 GET 请求检索 `examplebucket` 的生命周期配置。有关 API 操作的信息，请参阅 [GetBucketLifecycleConfiguration](https://docs.amazonaws.cn/AmazonS3/latest/API/API_GetBucketLifecycleConfiguration.html)。

```
GET ?lifecycle HTTP/1.1
Host: examplebucket.s3.amazonaws.com
Authorization: {{SignatureToBeCalculated}}
x-amz-date: 20130524T000000Z 
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
```

由于请求未提供任何正文内容，因此 `x-amz-content-sha256` 标头值是空请求正文的哈希值。以下步骤显示了签名计算。

1. 

**StringToSign**

   1. 

**CanonicalRequest**

       

      ```
      GET
      /
      lifecycle=
      host:examplebucket.s3.amazonaws.com
      x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      x-amz-date:20130524T000000Z
      
      host;x-amz-content-sha256;x-amz-date
      e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      ```

      在规范请求中，最后一行是空请求正文的哈希值。

   1. 

**StringToSign**

       

      ```
      AWS4-HMAC-SHA256
      20130524T000000Z
      20130524/us-east-1/s3/aws4_request
      9766c798316ff2757b517bc739a67f6213b4ab36dd5da2f94eaebf79c77395ca
      ```

       

1. 

**SigningKey**

    

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

    

1. 

**Signature**

    

   ```
   fea454ca298b7da1c68078a5d1bdbfbbe0d65c699e0f91ac7a200a0136783543
   ```

    

1. 

**Authorization 标头**

   生成的 `Authorization` 标头如下：

    

   ```
   AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=fea454ca298b7da1c68078a5d1bdbfbbe0d65c699e0f91ac7a200a0136783543
   ```

    

#### 示例：Get 存储桶（列出对象）
<a name="example-signature-list-bucket"></a>

以下示例从 `examplebucket` 存储桶中检索对象的列表。有关 API 操作的信息，请参阅 [ListObjects](https://docs.amazonaws.cn/AmazonS3/latest/API/API_ListObjects.html)。

```
GET ?max-keys=2&prefix=J HTTP/1.1
Host: examplebucket.s3.amazonaws.com
Authorization: {{SignatureToBeCalculated}}
x-amz-date: 20130524T000000Z 
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
```

由于请求未提供正文，因此 `x-amz-content-sha256` 的值是空请求正文的哈希值。以下步骤显示了签名计算。

1. 

**StringToSign**

   1. 

**CanonicalRequest**

       

      ```
      GET
      /
      max-keys=2&prefix=J
      host:examplebucket.s3.amazonaws.com
      x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      x-amz-date:20130524T000000Z
      
      host;x-amz-content-sha256;x-amz-date
      e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
      ```

      在规范请求中，最后一行是空请求正文的哈希值。

   1. 

**StringToSign**

       

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

       

1. 

**SigningKey**

    

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

    

1. 

**Signature**

    

   ```
   34b48302e7b5fa45bde8084f4b7868a86f0a534bc59db6670ed5711ef69dc6f7
   ```

    

1. 

**Authorization 标头**

   生成的 `Authorization` 标头如下：

    

   ```
   AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=34b48302e7b5fa45bde8084f4b7868a86f0a534bc59db6670ed5711ef69dc6f7
   ```

    