

# Authenticating Requests (AWS Signature Version 4)


**Topics**
+ [

## Authentication Methods
](#auth-methods-intro)
+ [

## Introduction to Signing Requests
](#signing-request-intro)
+ [

# Authenticating Requests: Using the Authorization Header (AWS Signature Version 4)
](sigv4-auth-using-authorization-header.md)
+ [

# Authenticating Requests: Using Query Parameters (AWS Signature Version 4)
](sigv4-query-string-auth.md)
+ [

# Examples: Signature Calculations in AWS Signature Version 4
](sig-v4-examples-using-sdks.md)
+ [

# Authenticating Requests: Browser-Based Uploads Using POST (AWS Signature Version 4)
](sigv4-authentication-HTTPPOST.md)
+ [

# Amazon S3 Signature Version 4 Authentication Specific Policy Keys
](bucket-policy-s3-sigv4-conditions.md)

Every interaction with Amazon S3 is either authenticated or anonymous. This section explains request authentication with the AWS Signature Version 4 algorithm.

 

**Note**  
If you use the AWS SDKs (see [Sample Code and Libraries](https://aws.amazon.com/code)) to send your requests, you don't need to read this section because the SDK clients authenticate your requests by using access keys that you provide. Unless you have a good reason not to, you should always use the AWS SDKs. In Regions that support both signature versions, you can request AWS SDKs to use specific signature version. For more information, see [Sending authenticated requests using the AWS SDKs](AuthUsingAcctOrUserCredentials.md#send-authenticated-request-SDKs). You need to read this section only if you are implementing the AWS Signature Version 4 algorithm in your custom client. 

Authentication with AWS Signature Version 4 provides some or all of the following, depending on how you choose to sign your request:

 
+ ** Verification of the identity of the requester** – Authenticated requests require a signature that you create by using your access keys (access key ID, secret access key). For information about getting access keys, see [Understanding and Getting Your Security Credentials](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html) in the *AWS General Reference*. If you are using temporary security credentials, the signature calculations also require a security token. For more information, see [Requesting Temporary Security Credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) in the *IAM User Guide*. 
+ **In-transit data protection** – In order to prevent tampering with a request while it is in transit, you use some of the request elements to calculate the request signature. Upon receiving the request, Amazon S3 calculates the signature by using the same request elements. If any request component received by Amazon S3 does not match the component that was used to calculate the signature, Amazon S3 will reject the request.
+ **Protect against reuse of the signed portions of the request** – The signed portions (using AWS Signatures) of requests are valid within 15 minutes of the timestamp in the request. An unauthorized party who has access to a signed request can modify the unsigned portions of the request without affecting the request's validity in the 15 minute window. Because of this, we recommend that you maximize protection by signing request headers and body, making HTTPS requests to Amazon S3, and by using the `s3:x-amz-content-sha256` condition key (see [Amazon S3 Signature Version 4 Authentication Specific Policy Keys](bucket-policy-s3-sigv4-conditions.md)) in AWS policies to require users to sign Amazon S3 request bodies. 



**Note**  
Amazon S3 supports Signature Version 4, a protocol for authenticating inbound API requests to AWS services, in all AWS Regions. At this time, AWS Regions created before January 30, 2014 will continue to support the previous protocol, Signature Version 2. Any new Regions after January 30, 2014 will support only Signature Version 4 and therefore all requests to those Regions must be made with Signature Version 4. For more information about AWS Signature Version 2, see [Signing and Authenticating REST Requests](https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAuthentication.html) in the *Amazon Simple Storage Service User Guide*. 

## Authentication Methods


You can express authentication information by using one of the following methods:

 
+ **HTTP Authorization header** – Using the HTTP `Authorization` header is the most common method of authenticating an Amazon S3 request. All of the Amazon S3 REST operations (except for browser-based uploads using POST requests) require this header. For more information about the `Authorization` header value, and how to calculate signature and related options, see [Authenticating Requests: Using the Authorization Header (AWS Signature Version 4)](sigv4-auth-using-authorization-header.md).
+ **Query string parameters** – You can use a query string to express a request entirely in a URL. In this case, you use query parameters to provide request information, including the authentication information. Because the request signature is part of the URL, this type of URL is often referred to as a presigned URL. You can use presigned URLs to embed clickable links, which can be valid for up to seven days, in HTML. For more information, see [Authenticating Requests: Using Query Parameters (AWS Signature Version 4)](sigv4-query-string-auth.md). 

 Amazon S3 also supports browser-based uploads that use HTTP POST requests. With an HTTP POST request, you can upload content to Amazon S3 directly from the browser. For information about authenticating POST requests, see [Browser-Based Uploads Using POST (AWS Signature Version 4)](sigv4-UsingHTTPPOST.md).





## Introduction to Signing Requests


Authentication information that you send in a request must include a signature. To calculate a signature, you first concatenate select request elements to form a string, referred to as the *string to sign*. You then use a signing key to calculate the hash-based message authentication code (HMAC) of the string to sign. 

In AWS Signature Version 4, you don't use your secret access key to sign the request. Instead, you first use your secret access key to derive a signing key. The derived signing key is specific to the date, service, and Region. For more information about how to derive a signing key in different programming languages, see [Examples of how to derive a signing key for Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html). 

The following diagram illustrates the general process of computing a signature.

![\[Diagram showing three-step process for computing a signature using StringToSign and signing key.\]](http://docs.aws.amazon.com/AmazonS3/latest/API/images/signing-overview.png)


The string to sign depends on the request type. For example, when you use the HTTP Authorization header or the query parameters for authentication, you use a varying combination of request elements to create the string to sign. For an HTTP POST request, the POST policy in the request is the string you sign. For more information about computing string to sign, follow links provided at the end of this section.

For signing key, the diagram shows series of calculations, where result of each step you feed into the next step. The final step is the signing key.

Upon receiving an authenticated request, Amazon S3 servers re-create the signature by using the authentication information that is contained in the request. If the signatures match, Amazon S3 processes your request; otherwise, the request is rejected. 

For more information about authenticating requests, see the following topics:
+ [Authenticating Requests: Using the Authorization Header (AWS Signature Version 4)](sigv4-auth-using-authorization-header.md)
+ [Authenticating Requests: Using Query Parameters (AWS Signature Version 4)](sigv4-query-string-auth.md)
+ [Browser-Based Uploads Using POST (AWS Signature Version 4)](sigv4-UsingHTTPPOST.md)

# Authenticating Requests: Using the Authorization Header (AWS Signature Version 4)
Using an Authorization Header

**Topics**
+ [

## Overview
](#sigv4-auth-header-overview)
+ [

# Signature Calculations for the Authorization Header: Transferring Payload in a Single Chunk (AWS Signature Version 4)
](sig-v4-header-based-auth.md)
+ [

# Signature Calculations for the Authorization Header: Transferring Payload in Multiple Chunks (Chunked Upload) (AWS Signature Version 4)
](sigv4-streaming.md)
+ [

# Signature calculations for trailing headers (chunked uploads) (AWS Signature Version 4)
](sigv4-streaming-trailers.md)



## Overview


Using the HTTP `Authorization` header is the most common method of providing authentication information. Except for [POST requests](RESTObjectPOST.md) and requests that are signed by using query parameters, all Amazon S3 operations use the `Authorization` request header to provide authentication information. 

The following is an example of the `Authorization` header value. Line breaks are added to this example for readability:

 

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



 The following table describes the various components of the `Authorization` header value in the preceding example:


| Component | Description | 
| --- | --- | 
| AWS4-HMAC-SHA256 |  The algorithm that was used to calculate the signature. You must provide this value when you use AWS Signature Version 4 for authentication. The string specifies AWS Signature Version 4 (`AWS4`) and the signing algorithm (`HMAC-SHA256`).  | 
| Credential |  Your access key ID and the scope information, which includes the date, Region, and service that were used to calculate the signature.  This string has the following form:  <pre><your-access-key-id>/<date>/<aws-region>/<aws-service>/aws4_request</pre> Where:  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html)  | 
| SignedHeaders |   A semicolon-separated list of request headers that you used to compute `Signature`. The list includes header names only, and the header names must be in lowercase. For example: <pre>host;range;x-amz-date</pre>  | 
| Signature | The 256-bit signature expressed as 64 lowercase hexadecimal characters. For example: <pre>fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024</pre>Note that the signature calculations vary depending on the option you choose to transfer the payload.  | 

The signature calculations vary depending on the method you choose to transfer the request payload. S3 supports the following options:

 
+ **Transfer payload in a single chunk** – In this case, you have the following signature calculation options:

   
  + **Signed payload option** – You can optionally compute the entire payload checksum and include it in signature calculation. This provides added security but you need to read your payload twice or buffer it in memory. 

    For example, in order to upload a file, you need to read the file first to compute a payload hash for signature calculation and again for transmission when you create the request. For smaller payloads, this approach might be preferable. However, for large files, reading the file twice can be inefficient, so you might want to upload data in chunks instead. 

    We recommend you include payload checksum for added security.
  + **Unsigned payload option** – Do not include payload checksum in signature calculation. 

  For step-by-step instructions to calculate signature and construct the Authorization header value, see [Signature Calculations for the Authorization Header: Transferring Payload in a Single Chunk (AWS Signature Version 4)](sig-v4-header-based-auth.md).
+ **Transfer payload in multiple chunks (chunked upload)** – In this case you transfer payload in chunks. You can transfer a payload in chunks regardless of the payload size.

  You can break up your payload into chunks. These can be fixed or variable-size chunks. By uploading data in chunks, you avoid reading the entire payload to calculate the signature. Instead, for the first chunk, you calculate a seed signature that uses only the request headers. The second chunk contains the signature for the first chunk, and each subsequent chunk contains the signature for the chunk that precedes it. At the end of the upload, you send a final chunk with 0 bytes of data that contains the signature of the last chunk of the payload. For more information, see [Signature Calculations for the Authorization Header: Transferring Payload in Multiple Chunks (Chunked Upload) (AWS Signature Version 4)](sigv4-streaming.md). 

When signing your requests, you can use either AWS Signature Version 4 or AWS Signature Version 4A. The key difference between the two is determined by how the signature is calculated. With AWS Signature Version 4A, the signature does not include Region-specific information and is calculated using the `AWS4-ECDSA-P256-SHA256` algorithm.

In addition to these options, you have the option of including a trailer with your request. In order to include a trailer with your request, you need to specify that in the header by setting `x-amz-content-sha256` to the appropriate value. If you are using a trailing header, you must include `x-amz-trailer` in the header and specify the trailing header names as a string in a comma-separated list. All trailing headers are written after the final chunk. If you're uploading the data in multiple chunks, you must send a final chunk with 0 bytes of data before sending the trailing header. 

When you send a request, you must tell Amazon S3 which of the preceding options you have chosen in your signature calculation, by adding the `x-amz-content-sha256` header with one of the following values:

 


| Header value | Description | 
| --- | --- | 
|  Actual payload checksum value  |  This value is the actual checksum of your object and is only possible when you are uploading the data in a single chunk.  | 
|  UNSIGNED-PAYLOAD  |  Use this when you are uploading the object as a single unsigned chunk.  | 
|  STREAMING-UNSIGNED-PAYLOAD-TRAILER  |  Use this when sending an unsigned payload over multiple chunks. In this case you also have a trailing header after the chunk is uploaded.  | 
|  STREAMING-AWS4-HMAC-SHA256-PAYLOAD  |  Use this when sending a payload over multiple chunks, and the chunks are signed using `AWS4-HMAC-SHA256`. This produces a SigV4 signature.  | 
|  STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILER  |  Use this when sending a payload over multiple chunks, and the chunks are signed using `AWS4-HMAC-SHA256`. This produces a SigV4 signature. In addition, the digest for the chunks is included as a trailing header.  | 
|  STREAMING-AWS4-ECDSA-P256-SHA256-PAYLOAD  |  Use this when sending a payload over multiple chunks, and the chunks are signed using `AWS4-ECDSA-P256-SHA256`. This produces a SigV4A signature.  | 
|  STREAMING-AWS4-ECDSA-P256-SHA256-PAYLOAD-TRAILER  |  Use this when sending a payload over multiple chunks, and the chunks are signed using `AWS4-ECDSA-P256-SHA256`. This produces a SigV4A signature. In addition, the digest for the chunks is included as a trailing header.  | 



Upon receiving the request, Amazon S3 re-creates the string to sign using information in the `Authorization` header and the `date` header. It then verifies with authentication service the signatures match. The request date can be specified by using either the HTTP `Date` or the `x-amz-date` header. If both headers are present, `x-amz-date` takes precedence. 

If the signatures match, Amazon S3 processes your request; otherwise, your request will fail. 



For more information, see the following topics:

[Signature Calculations for the Authorization Header: Transferring Payload in a Single Chunk (AWS Signature Version 4)](sig-v4-header-based-auth.md)

[Signature Calculations for the Authorization Header: Transferring Payload in Multiple Chunks (Chunked Upload) (AWS Signature Version 4)](sigv4-streaming.md)

[Signature calculations for trailing headers (chunked uploads) (AWS Signature Version 4)](sigv4-streaming-trailers.md)

# Signature Calculations for the Authorization Header: Transferring Payload in a Single Chunk (AWS Signature Version 4)
Signature Calculation: Transfer Payload in a Single Chunk

When using the `Authorization` header to authenticate requests, the header value includes, among other things, a signature. The signature calculations vary depending on the choice you make for transferring the payload ([Overview](sigv4-auth-using-authorization-header.md#sigv4-auth-header-overview)). This section explains signature calculations when you choose to transfer the payload in a single chunk. The example section (see [Examples: Signature Calculations](#example-signature-calculations)) shows signature calculations and resulting `Authorization` headers that you can use as a test suite to verify your code.

**Important**  
When transferring payload in a single chunk, you can optionally choose to include the payload hash in the signature calculations, referred as *signed payload* (if you don't include it, the payload is considered *unsigned*). The signing procedure discussed in the following section applies to both, but note the following differences:  
   
**Signed payload option** – You include the payload hash when constructing the canonical request (that then becomes part of StringToSign, as explained in the signature calculation section). You also specify the same value as the `x-amz-content-sha256` header value when sending the request to S3.
**Unsigned payload option** – You include the literal string `UNSIGNED-PAYLOAD` when constructing a canonical request, and set the same value as the `x-amz-content-sha256` header value when sending the request to Amazon S3.
When you send your request to Amazon S3, the `x-amz-content-sha256` header value informs Amazon S3 whether the payload is signed or not. Amazon S3 can then create the signature accordingly for verification.  
In both cases, because the `x-amz-content-sha256` header value is already part of your `HashedPayload`, you are not required to include the `x-amz-content-sha256` header as a canonical header.

## Calculating a Signature


To calculate a signature, you first need a string to sign. You then calculate a `HMAC-SHA256` hash of the string to sign by using a signing key. The following diagram illustrates the process, including the various components of the string that you create for signing 

When Amazon S3 receives an authenticated request, it computes the signature and then compares it with the signature that you provided in the request. For that reason, you must compute the signature by using the same method that is used by Amazon S3. The process of putting a request in an agreed-upon form for signing is called canonicalization.

 

![\[AWS4-HMAC-SHA256 signature process diagram showing canonical request, StringToSign, and signature steps.\]](http://docs.aws.amazon.com/AmazonS3/latest/API/images/sigV4-using-auth-header.png)


The following table describes the functions that are shown in the diagram. You need to implement code for these functions.


| Function | Description | 
| --- | --- | 
| Lowercase() | Convert the string to lowercase. | 
| Hex() | Lowercase base 16 encoding. | 
| SHA256Hash() | Secure Hash Algorithm (SHA) cryptographic hash function. | 
| HMAC-SHA256() | Computes HMAC by using the SHA256 algorithm with the signing key provided. This is the final signature. | 
| Trim() | Remove any leading or trailing whitespace.  | 
| UriEncode() |  URI encode every byte. UriEncode() must enforce the following rules: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html)  The standard UriEncode functions provided by your development platform may not work because of differences in implementation and related ambiguity in the underlying RFCs. We recommend that you write your own custom UriEncode function to ensure that your encoding will work.  To see an example of a UriEncode function in Java, see [Java Utilities](https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66) on the GitHub website.  | 

### Task 1: Create a Canonical Request


This section provides an overview of creating a canonical request. 

The following is the canonical request format that Amazon S3 uses to calculate a signature. For signatures to match, you must create a canonical request in this format: 

 

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

Where:

 
+ *HTTPMethod* is one of the HTTP methods, for example GET, PUT, HEAD, and DELETE.
+ *CanonicalURI* is the URI-encoded version of the absolute path component of the URI—everything starting with the "/" that follows the domain name and up to the end of the string or to the question mark character ('?') if you have query string parameters. The URI in the following example, `/examplebucket/myphoto.jpg`, is the absolute path and you don't encode the "/" in the absolute path:

   

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

   
**Note**  
You do not normalize URI paths for requests to Amazon S3. For example, you may have a bucket with an object named "my-object//example//photo.user". Normalizing the path changes the object name in the request to "my-object/example/photo.user". This is an incorrect path for that object.
+ *CanonicalQueryString* specifies the URI-encoded query string parameters. You URI-encode name and values individually. You must also sort the parameters in the canonical query string alphabetically by key name. The sorting occurs after encoding. The query string in the following URI example is `prefix=somePrefix&marker=someMarker&max-keys=20`:

   

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

  The canonical query string is as follows (line breaks are added to this example for readability):

   

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

  When a request targets a subresource, the corresponding query parameter value will be an empty string (""). For example, the following URI identifies the `ACL` subresource on the `examplebucket` bucket:

   

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

  The CanonicalQueryString in this case is as follows:

   

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

  If the URI does not include a '?', there is no query string in the request, and you set the canonical query string to an empty string (""). You will still need to include the "\$1n".
+ *CanonicalHeaders* is a list of request headers with their values. Individual header name and value pairs are separated by the newline character ("\$1n"). Header names must be in lowercase. You must sort the header names alphabetically to construct the string, as shown in the following example:

   

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

  The `Lowercase()` and `Trim()` functions used in this example are described in the preceding section. 

  The *CanonicalHeaders* list must include the following: 
  + HTTP `host` header.
  + If the `Content-MD5` header is present in the request, you must add it to the *CanonicalHeaders* list. 
  + Any `x-amz-*` headers that you plan to include in your request must also be added. For example, if you are using temporary security credentials, you need to include `x-amz-security-token` in your request. You must add this header in the list of *CanonicalHeaders*.
**Note**  
The `x-amz-content-sha256` header is required for all AWS Signature Version 4 requests. It provides a hash of the request payload. However, you are not required to include the `x-amz-content-sha256` as a canonical header because S3 will automatically use its value when calculating the payload hash sent in the request.
If there is no payload, you must provide the hash of an empty string. 
If you do not want S3 to check against the hash of the request, you can use the literal string `"UNSIGNED-PAYLOAD"` instead.

  The following are example `CanonicalHeaders` strings. The header names are in lowercase and sorted.  
**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
  ```
**Note**  
For the purpose of calculating an authorization signature, the host header and all `x-amz-*` headers, excluding `x-amz-content-sha256`, are required. However, in order to prevent data tampering, you should consider including all the headers in the signature calculation.  
Signing the `x-amz-content-sha256` header is optional because S3 will use its value when calculating the received request payload hash. 
+ *SignedHeaders* is an alphabetically sorted, semicolon-separated list of lowercase request header names. The request headers in the list are the same headers that you included in the `CanonicalHeaders` string. In the previous examples, the value of *SignedHeaders* would be as follows:

    
**Examples 1 and 2**  

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

  ```
  host;x-amz-date
  ```
+ *HashedPayload* is the hexadecimal value of the SHA256 hash of the request payload. 

   

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

  If there is no payload in the request, you compute a hash of the empty string as follows:

   

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

  The hash returns the following value:

   

  ```
  e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  
  ```

  For example, when you upload an object by using a PUT request, you provide object data in the body. When you retrieve an object by using a GET request, you compute the empty string hash. 

### Task 2: Create a String to Sign


This section provides an overview of creating a string to sign. For step-by-step instructions, see [Task 2: Create a String to Sign](https://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html) in the *AWS General Reference*.

The string to sign is a concatenation of the following strings:

 

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

The constant string `AWS4-HMAC-SHA256` specifies the hash algorithm that you are using, HMAC-SHA256. The `timeStamp` is the current UTC time in ISO 8601 format (for example, `20130524T000000Z`). 

`Scope` binds the resulting signature to a specific date, an AWS Region, and a service. Thus, your resulting signature will work only in the specific Region and for a specific service. The signature is valid for seven days after the specified date.

 

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

 For Amazon S3, the service string is `s3`. For a list of *region* strings, see [Regions and Endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the *AWS General Reference*. The Region column in this table provides the list of valid Region strings.

 The following scope restricts the resulting signature to the `us-east-1` Region and Amazon S3. 

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

 

**Note**  
 `Scope` must use the same date that you use to compute the signing key, as discussed in the following section. 

### Task 3: Calculate Signature


 In AWS Signature Version 4, instead of using your AWS access keys to sign a request, you first create a signing key that is scoped to a specific Region and service.  For more information about signing keys, see [Introduction to Signing Requests](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")
```

 

**Note**  
Some use cases can process signature keys for up to 7 days. For more information see [Share an Object with Others](https://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURL.html).

For a list of Region strings, see [Regions and Endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the *AWS General Reference*.

 Using a signing key enables you to keep your AWS credentials in one safe place. For example, if you have multiple servers that communicate with Amazon S3, you share the signing key with those servers; you don’t have to keep a copy of your secret access key on each server. Signing key is valid for up to seven days. So each time you calculate signing key you will need to share the signing key with your servers. For more information, see [Authenticating Requests (AWS Signature Version 4)](sig-v4-authenticating-requests.md).

The final signature is the HMAC-SHA256 hash of the string to sign, using the signing key as the key.

 

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

For step-by-step instructions on creating a signature, see [Task 3: Create a Signature](https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html) in the *AWS General Reference*.

### Examples: Signature Calculations


You can use the examples in this section as a reference to check signature calculations in your code. The calculations shown in the examples use the following data:

 
+  Example access keys.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html)
+ Request timestamp of 20130524T000000Z (`Fri, 24 May 2013 00:00:00 GMT`).
+ Bucket name `examplebucket`.
+ The bucket is assumed to be in the US East (N. Virginia) Region. The credential `Scope` and the `Signing Key` calculations use `us-east-1` as the Region specifier. For information about other Regions, see [Regions and Endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the *AWS General Reference*. 
+ You can use either path-style or virtual hosted–style requests. The following examples show how to sign a virtual hosted–style request, for example:

   

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

  For more information, see [Virtual Hosting of Buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html) in the *Amazon Simple Storage Service User Guide*.

#### Example: GET Object


The following example gets the first 10 bytes of an object (test.txt) from `examplebucket`. For more information about the API action, see [GetObject](API_GetObject.md).

 

```
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
```

Because this GET request does not provide any body content, the `x-amz-content-sha256` value can either be the hash of the empty request body or the literal string `"UNSIGNED-PAYLOAD"`. The following steps show signature calculations and construction of the `Authorization` header using the hash of an empty string. 

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
      ```

      In the canonical request string, the last line is the hash of the empty request body. The third line is empty because there are no query parameters in the request. 

   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 header**

   The resulting `Authorization` header is as follows: 

    

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

    

#### Example: PUT Object


This example PUT request creates an object (`test$file.text`) in `examplebucket` . The example assumes the following:

 
+ You are requesting `REDUCED_REDUNDANCY` as the storage class by adding the `x-amz-storage-class` request header. For information about storage classes, see [Storage Classes](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingMetadata.html#storage-class-intro) in the *Amazon Simple Storage Service User Guide*.
+ The content of the uploaded file is a string, `"Welcome to Amazon S3."` The value of `x-amz-content-sha256` in the request is based on this string.

For information about the API action, see [PutObject](API_PutObject.md). 

```
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>
```



The following steps show signature calculations.

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
      ```

      In the canonical request, the third line is empty because there are no query parameters in the request. The `x-amz-content-sha256` canonical header may optionally be signed since its payload hash is already provided at the bottom of the request. The last line is the hash of the body, which should be the same as the `x-amz-content-sha256 header` value sent to S3 in the HTTP request.

   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 header**

   The resulting `Authorization` header is as follows:

    

   ```
   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
   ```

    

#### Example: GET Bucket Lifecycle


The following GET request retrieves the lifecycle configuration of `examplebucket`. For information about the API action, see [GetBucketLifecycleConfiguration](API_GetBucketLifecycleConfiguration.md). 

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

Because the request does not provide any body content, the `x-amz-content-sha256` header value is the hash of the empty request body. The following steps show signature calculations.

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
      ```

      In the canonical request, the last line is the hash of the empty request body. 

   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 header**

   The resulting `Authorization` header is as follows: 

    

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

    

#### Example: Get Bucket (List Objects)


The following example retrieves a list of objects from `examplebucket` bucket. For information about the API action, see [ListObjects](API_ListObjects.md). 

```
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
```

Because the request does not provide a body, the value of `x-amz-content-sha256` is the hash of the empty request body. The following steps show signature calculations.

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
      ```

      In the canonical string, the last line is the hash of the empty request body. 

   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 header**

   The resulting `Authorization` header is as follows: 

    

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

    

# Signature Calculations for the Authorization Header: Transferring Payload in Multiple Chunks (Chunked Upload) (AWS Signature Version 4)
Signature Calculation: Transfer Payload in Multiple Chunks

As described in the [Overview](sigv4-auth-using-authorization-header.md#sigv4-auth-header-overview), when authenticating requests using the `Authorization` header, you have an option of uploading the payload in chunks. You can send data in fixed size or variable size chunks. This section describes the signature calculation process in chunked upload, how you create the chunk body, and how the delayed signing works where you first upload the chunk, and send its signature in the subsequent chunk. The example section (see [Example: PUT Object](#example-signature-calculations-streaming)) shows signature calculations and resulting `Authorization` headers that you can use as a test suite to verify your code.

 

**Note**  
When transferring data in a series of chunks, you must do one of the following:   
Explicitly specify the total content length (object length in bytes plus metadata in each chunk) using the `Content-Length` HTTP header. To do this, you must pre-compute the total length of the payload, including the metadata that you send in each chunk, before starting your request.
Specify the `Transfer-Encoding` HTTP header. If you include the `Transfer-Encoding` header and specify any value other than `identity`, you must omit the `Content-Length` header.
  
For all requests, you must include the `x-amz-decoded-content-length` header, specifying the size of the object in bytes.  


Each chunk signature calculation includes the signature of the previous chunk. To begin, you create a *seed* signature using only the headers. You use the seed signature in the signature calculation of the first chunk. For each subsequent chunk, you create a chunk signature that includes the signature of the previous chunk. Thus, the chunk signatures are chained together; that is, the signature of chunk *n* is a function *F(chunk n, signature(chunk n-1))*. The chaining ensures that you send the chunks in the correct order.



To perform a chunked upload, do the following:

 

1. Decide the payload chunk size. You need this when you write the code.

   The chunk size must be at least 8 KB. We recommend a chunk size of a least 64 KB for better performance. This chunk size applies to all chunks except the last one. The last chunk you send can be smaller than 8 KB. If your payload is small and can fit into one chunk, then it can be smaller than the 8 KB.

1. Create the seed signature for inclusion in the first chunk. For more information, see [Calculating the Seed Signature](#sigv4-chunked-upload-sig-calculation-chunk0).

1. Create the first chunk and stream it. For more information, see [Defining the Chunk Body](#sigv4-chunked-body-definition).

1. For each subsequent chunk, calculate the chunk signature that includes the previous signature in the string you sign, construct the chunk, and send it. For more information, see [Defining the Chunk Body](#sigv4-chunked-body-definition).

1. Send the final additional chunk, which is the same as the other chunks in the construction, but it has zero data bytes. For more information, see [Defining the Chunk Body](#sigv4-chunked-body-definition).

## Calculating the Seed Signature


The following diagram illustrates the process of calculating the seed signature.

 

![\[Diagram showing the process of calculating the seed signature.\]](http://docs.aws.amazon.com/AmazonS3/latest/API/images/sigV4-auth-header-chunked-seed-signature.png)


The following table describes the functions that are shown in the diagram. You need to implement code for these functions.


| Function | Description | 
| --- | --- | 
| Lowercase() | Convert the string to lowercase. | 
| Hex() | Lowercase base 16 encoding. | 
| SHA256Hash() | Secure Hash Algorithm (SHA) cryptographic hash function. | 
| HMAC-SHA256() | Computes HMAC by using the SHA256 algorithm with the signing key provided. This is the final signature. | 
| Trim() | Remove any leading or trailing whitespace.  | 
| UriEncode() |  URI encode every byte. UriEncode() must enforce the following rules: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html)  The standard UriEncode functions provided by your development platform may not work because of differences in implementation and related ambiguity in the underlying RFCs. We recommend that you write your own custom UriEncode function to ensure that your encoding will work.  To see an example of a UriEncode function in Java, see [Java Utilities](https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66) on the GitHub website.  | 

For information about the signing process, see [Signature Calculations for the Authorization Header: Transferring Payload in a Single Chunk (AWS Signature Version 4)](sig-v4-header-based-auth.md). The process is the same, except that the creation of `CanonicalRequest` differs as follows:
+ In addition to the request headers you plan to add, you must include the following headers:    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html)

You send the first chunk with the seed signature. You must construct the chunk as described in the following section.

## Defining the Chunk Body


All chunks include some metadata. Each chunk must conform to the following structure:

 

```
string(IntHexBase(chunk-size)) + ";chunk-signature=" + signature + \r\n + chunk-data + \r\n                    
```

Where:

 
+ `IntHexBase()` is a function that you write to convert an integer chunk-size to hexadecimal. For example, if chunk-size is 65536, hexadecimal string is "10000".
+ *chunk-size* is the size, in bytes, of the chunk-data, without metadata. For example, if you are uploading a 65 KB object and using a chunk size of 64 KB, you upload the data in three chunks: the first would be 64 KB, the second 1 KB, and the final chunk with 0 bytes.
+ *signature* For each chunk, you calculate the signature using the following string to sign. For the first chunk, you use the seed-signature as the previous signature. 

  

     
![\[Diagram of the process of calculating the seed signature showing various components of the string to sign.\]](http://docs.aws.amazon.com/AmazonS3/latest/API/images/sigV4-auth-header-chunk-signature.png)



 The size of the final chunk data that you send is 0, although the chunk body still contains metadata, including the signature of the previous chunk.

## Example: PUT Object


You can use the examples in this section as a reference to check signature calculations in your code. Before you review the examples, note the following:

 
+  The signature calculations in these examples use the following example security credentials.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html)
+ All examples use the request timestamp 20130524T000000Z (`Fri, 24 May 2013 00:00:00 GMT`).
+ All examples use `examplebucket` as the bucket name.
+ The bucket is assumed to be in the US East (N. Virginia) Region, and the credential `Scope` and the `Signing Key` calculations use `us-east-1` as the Region specifier.  For more information, see [Regions and Endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the *Amazon Web Services General Reference*. 
+ You can use either path style or virtual-hosted style requests. The following examples use virtual-hosted style requests, for example: 

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

  For more information, see [Virtual Hosting of Buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html) in the *Amazon Simple Storage Service User Guide*.

The following example sends a `PUT` request to upload an object. The signature calculations assume the following:

 
+ You are uploading a 65 KB text file, and the file content is a one-character string made up of the letter 'a'. 
+ The chunk size is 64 KB. As a result, the payload is uploaded in three chunks, 64 KB, 1 KB, and the final chunk with 0 bytes of chunk data. 
+ The resulting object has the key name `chunkObject.txt`.
+ You are requesting `REDUCED_REDUNDANCY` as the storage class by adding the `x-amz-storage-class` request header.

For information about the API action, see [PutObject](API_PutObject.md). The general request syntax is as follows: 

```
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
Content-Encoding: aws-chunked
x-amz-decoded-content-length: 66560
Content-Length: 66824
<Payload>
```



The following steps show signature calculations.

1. 

**Seed signature — Create String to Sign**

   1. 

**CanonicalRequest**

       

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

      In the canonical request, the third line is empty because there are no query parameters in the request. The last line is the constant string provided as the value of the hashed Payload, which should be same as the value of `x-amz-content-sha256 header`.

   1. 

**StringToSign**

       

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

       

       
**Note**  
For information about each of line in the string to sign, see the diagram that explains seed signature calculation.

1. 

**SigningKey**

    

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

    

1. 

**Seed Signature**

    

   ```
   4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9
   ```

    

1. 

**Authorization header**

   The resulting Authorization header is as follows:

    

   ```
   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=4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9
   ```

    

1. 

**Chunk 1: (65536 bytes, with value 97 for letter 'a')**

   1. Chunk string to sign:

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

       
**Note**  
For information about each line in the string to sign, see the preceding diagram that shows various components of the string to sign (for example, the last three lines are, `previous-signature`, `hash("")`, and `hash(current-chunk-data)`).

   1. Chunk signature:

      ```
      ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648
      ```

   1. Chunk data sent:

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

1. 

**Chunk 2: (1024 bytes, with value 97 for letter 'a')**

   1. Chunk string to sign:

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

   1. Chunk signature:

      ```
      0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497
      ```

   1. Chunk data sent:

      ```
      400;chunk-signature=0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497
      <1024 bytes>
      ```

1. 

**Chunk 3: (0 byte data)**

   1. Chunk string to sign:

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

   1. Chunk signature:

      ```
      b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9
      ```

   1. Chunk data sent:

      ```
      0;chunk-signature=b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9
      ```

# Signature calculations for trailing headers (chunked uploads) (AWS Signature Version 4)
Signature Calculation: Including Trailing Headers

When authenticating requests using the `Authorization` header, you can also upload the payload in chunks. When you send the data for the object in chunks, you also have the option of including trailing headers. (For more information, see [Signature Calculations for the Authorization Header: Transferring Payload in Multiple Chunks (Chunked Upload) (AWS Signature Version 4)](sigv4-streaming.md).) This section describes the steps you need to take when you want to include a trailing header at the end of your multiple chunk upload.

 

**Important**  
When you are including trailing headers, you must send the following in your initial header:   
You must set `x-amz-content-sha256` to an appropriate value that indicates a trailer will be included. To see the acceptable values for `x-amz-content-sha256`, see [Authenticating Requests: Using the Authorization Header (AWS Signature Version 4)](sigv4-auth-using-authorization-header.md).
You must set `x-amz-trailer` to indicate the contents your are including in your trailing header.

 Trailing headers are only sent after the chunks have been uploaded. Previous chunks are sent as normal and signed as described in the previous sections, including sending the final chunk with a payload of 0 bytes. The trailing headers are included as their own chunk and sent after the final chunk with a payload of 0 bytes. For example, if your data ended with a 100 KB chunk, you would send the following: 
+ Previous data chunks
+ 100 KB final chunk of the object
+ 0 bytes chunk signifying the end of the object
+ Trailing headers chunk

## Examples: Checking signature calculations


You can use the examples in this section as a reference to check signature calculations in your code. Before you review the examples, note the following:

 
+  The signature calculations in these examples use the following example security credentials.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming-trailers.html)
+ All examples use the request timestamp 20130524T000000Z (`Fri, 24 May 2013 00:00:00 GMT`).
+ All examples use `examplebucket` as the bucket name.
+ The bucket is assumed to be in the US East (N. Virginia) Region, and the credential `Scope` and the `Signing Key` calculations use `us-east-1` as the Region specifier.  For more information, see [Regions and endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the *Amazon Web Services General Reference*. 
+ You can use either path style or virtual-hosted style requests. The following examples use virtual-hosted style requests, for example: 

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

  For more information, see [Virtual Hosting of Buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html) in the *Amazon Simple Storage Service User Guide*.

The following example sends a `PUT` request to upload an object. The signature calculations assume the following:

 
+ You are uploading a 65 KB text file, and the file content is a one-character string made up of the letter 'a'. 
+ The chunk size is 64 KB. As a result, the payload is uploaded in three chunks, 64 KB, 1 KB, and the final chunk with 0 bytes of chunk data. 
+ The resulting object has the key name `chunkObject.txt`.
+ You are requesting `REDUCED_REDUNDANCY` as the storage class by adding the `x-amz-storage-class` request header.
+ The transfer is including a CRC32C checksum value as a trailing header.

For information about the API action, see [PutObject](API_PutObject.md). The general request syntax is as follows: 

```
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: 66824
<Payload>
```



The following steps show signature calculations.

1. 

**Seed signature — Create String to Sign**

   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
      ```

      In the canonical request, the third line is empty because there are no query parameters in the request. The last line is the constant string provided as the value of the hashed Payload, which should be same as the value of `x-amz-content-sha256 header`.

   1. 

**StringToSign**

       

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

       

       
**Note**  
For information about each of line in the string to sign, see the diagram that explains seed signature calculation.

1. 

**SigningKey**

    

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

    

1. 

**Seed Signature**

    

   ```
   106e2a8a18243abcf37539882f36619c00e2dfc72633413f02d3b74544bfeb8e
   ```

    

1. 

**Authorization header**

   The resulting Authorization header is as follows:

    

   ```
   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. 

**Chunk 1: (65536 bytes, with value 97 for letter 'a')**

   1. Chunk string to sign:

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

       
**Note**  
For information about each line in the string to sign, see the diagram in the preceding topic ([Calculating the Seed Signature](sigv4-streaming.md#sigv4-chunked-upload-sig-calculation-chunk0)) that shows various components of the string to sign. For example, the last three lines consist of the following:  
*previous-signature*
`hash("")`
`hash(current-chunk-data)`

   1. Chunk signature:

      ```
      b474d8862b1487a5145d686f57f013e54db672cee1c953b3010fb58501ef5aa2
      ```

   1. Chunk data sent:

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

1. 

**Chunk 2: (1024 bytes, with value 97 for letter 'a')**

   1. Chunk string to sign:

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

   1. Chunk signature:

      ```
      1c1344b170168f8e65b41376b44b20fe354e373826ccbbe2c1d40a8cae51e5c7
      ```

   1. Chunk data sent:

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

1. 

**Chunk 3: (0 byte data)**

   1. Chunk string to sign:

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

   1. Chunk signature:

      ```
      2ca2aba2005185cf7159c6277faf83795951dd77a3a99e6e65d5c9f85863f992
      ```

   1. Chunk data sent:

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

1. 

**Chunk 4: Trailing headers**

   1. Trailer chunk string to sign:

      ```
      AWS4-HMAC-SHA256-TRAILER
      20130524T000000Z
      20130524/us-east-1/s3/aws4_request
      2ca2aba2005185cf7159c6277faf83795951dd77a3a99e6e65d5c9f85863f992
      1e376db7e1a34a8ef1c4bcee131a2d60a1cb62503747488624e10995f448d774
      ```
**Note**  
The last two lines are `previous-signature` (the 0 byte data chunk signature), `hash`(*trailing-checksum-header-name*:*base64-encoded-trailing-checksum-value*\$1n).  
The hash is calculated as follows with no whitespace:   
The trailing checksum header name
A colon (`:`)
The base64-encoded trailing checksum value
A newline character (`\n`). 
In this example, where we are using the `crc32c` hash algorithm, with the base64-encoded checksum value `sOO8/Q==`, we can represent the computation as follows: `hash('x-amz-checksum-crc32c:sOO8/Q==\n')`.

   1. Chunk signature:

      ```
      d81f82fc3505edab99d459891051a732e8730629a2e4a59689829ca17fe2e435
      ```

   1. Chunk data sent:

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

# Authenticating Requests: Using Query Parameters (AWS Signature Version 4)
Using Query Parameters

As described in the authentication overview (see [Authentication Methods](sig-v4-authenticating-requests.md#auth-methods-intro)), you can provide authentication information using query string parameters. Using query parameters to authenticate requests is useful when you want to express a request entirely in a URL. This method is also referred as presigning a URL. 

A use case scenario for presigned URLs is that you can grant temporary access to your Amazon S3 resources. For example, you can embed a presigned URL on your website or alternatively use it in command line client (such as Curl) to download objects.

**Note**  
You can also use the AWS CLI to create presigned URLs. For more information, see [https://docs.aws.amazon.com/cli/latest/reference/s3/presign.html](https://docs.aws.amazon.com/cli/latest/reference/s3/presign.html) in the *AWS CLI Command Reference*.

The following is an example presigned URL. 

 

```
https://examplebucket.s3.amazonaws.com/test.txt
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=<your-access-key-id>/20130721/us-east-1/s3/aws4_request
&X-Amz-Date=20130721T201207Z
&X-Amz-Expires=86400
&X-Amz-SignedHeaders=host
&X-Amz-Signature=<signature-value>
```



In the example URL, note the following:

 
+ The line feeds are added for readability.
+ The `X-Amz-Credential` value in the URL shows the "/" character only for readability. In practice, it should be encoded as `%2F`. For example:

   

  ```
  &X-Amz-Credential=<your-access-key-id>%2F20130721%2Fus-east-1%2Fs3%2Faws4_request
  ```

  

The following table describes the query parameters in the URL that provide authentication information. 


| Query String Parameter Name | Example Value | 
| --- | --- | 
| X-Amz-Algorithm |  Identifies the version of AWS Signature and the algorithm that you used to calculate the signature.  For AWS Signature Version 4, you set this parameter value to `AWS4-HMAC-SHA256`. This string identifies AWS Signature Version 4 (AWS4) and the HMAC-SHA256 algorithm (HMAC-SHA256).   | 
| X-Amz-Credential |  In addition to your access key ID, this parameter also provides scope (AWS Region and service) for which the signature is valid. This value must match the scope you use in signature calculations, discussed in the following section. The general form for this parameter value is as follows:  <pre><your-access-key-id>/<date>/<AWS Region>/<AWS-service>/aws4_request</pre> For example:   <pre>AKIAIOSFODNN7EXAMPLE/20130721/us-east-1/s3/aws4_request</pre> For Amazon S3, the *AWS-service* string is `s3`. For a list of S3 `AWS-region` strings, see [Regions and Endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the *AWS General Reference*. | 
| X-Amz-Date |  The date and time format must follow the ISO 8601 standard, and must be formatted with the "*yyyyMMdd*T*HHmmss*Z" format. For example if the date and time was "08/01/2016 15:32:41.982-700" then it must first be converted to UTC (Coordinated Universal Time) and then submitted as "20160801T223241Z".   | 
| X-Amz-Expires |  Provides the time period, in seconds, for which the generated presigned URL is valid. For example, `86400` (24 hours). This value is an integer. The minimum value you can set is 1, and the maximum is 604800 (seven days). A presigned URL can be valid for a maximum of seven days because the signing key you use in signature calculation is valid for up to seven days.  | 
| X-Amz-SignedHeaders |  Lists the headers that you used to calculate the signature. The following headers are required in the signature calculations:  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html)    For added security, you should sign all the request headers that you plan to include in your request.   | 
| X-Amz-Signature |  Provides the signature to authenticate your request. This signature must match the signature Amazon S3 calculates; otherwise, Amazon S3 denies the request. For example, ` 733255ef022bec3f2a8701cd61d4b371f3f28c9f193a1f02279211d48d5193d7` Signature calculations are described in the following section.  | 
| X-Amz-Security-Token |  Optional credential parameter if using credentials sourced from the STS service.  | 



## Calculating a Signature


The following diagram illustrates the signature calculation process. 

 

![\[Diagram showing AWS request signing process with Canonical Request, StringToSign, and Signature steps.\]](http://docs.aws.amazon.com/AmazonS3/latest/API/images/sigV4-using-query-params.png)




The following table describes the functions that are shown in the diagram. You need to implement code for these functions.


| Function | Description | 
| --- | --- | 
| Lowercase() | Convert the string to lowercase. | 
| Hex() | Lowercase base 16 encoding. | 
| SHA256Hash() | Secure Hash Algorithm (SHA) cryptographic hash function. | 
| HMAC-SHA256() | Computes HMAC by using the SHA256 algorithm with the signing key provided. This is the final signature. | 
| Trim() | Remove any leading or trailing whitespace.  | 
| UriEncode() |  URI encode every byte. UriEncode() must enforce the following rules: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html)  The standard UriEncode functions provided by your development platform may not work because of differences in implementation and related ambiguity in the underlying RFCs. We recommend that you write your own custom UriEncode function to ensure that your encoding will work.  To see an example of a UriEncode function in Java, see [Java Utilities](https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-core/src/main/java/com/amazonaws/util/SdkHttpUtils.java#L66) on the GitHub website.  | 

For more information about the signing process (details of creating a canonical request, string to sign, and signature calculations), see [Signature Calculations for the Authorization Header: Transferring Payload in a Single Chunk (AWS Signature Version 4)](sig-v4-header-based-auth.md). The process is generally the same except that the creation of **CanonicalRequest** in a presigned URL differs as follows:

 
+ You don't include a payload hash in the **Canonical Request**, because when you create a presigned URL, you don't know the payload content because the URL is used to upload an arbitrary payload. Instead, you use a constant string `UNSIGNED-PAYLOAD`. 
+ The **Canonical Query String** must include all the query parameters from the preceding table except for `X-Amz-Signature`. 
+ For S3, you must include the `X-Amz-Security-Token` query parameter in the URL if using credentials sourced from the STS service.
+ **Canonical Headers** must include the HTTP `host` header. If you plan to include any of the `x-amz-* ` headers, these headers must also be added for signature calculation. You can optionally add all other headers that you plan to include in your request. For added security, you should sign as many headers as possible. If you add a signed header that is also a signed query parameter, and they differ in value, you will receive an `InvalidRequest` error as the input is conflicting.

## An Example


Suppose you have an object `test.txt` in your `examplebucket` bucket. You want to share this object with others for a period of 24 hours (86400 seconds) by creating a presigned URL. 

 

```
https://examplebucket.s3.amazonaws.com/test.txt
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request
&X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host
&X-Amz-Signature=<signature-value>
```

The following steps illustrate first the signature calculations and then construction of the presigned URL. The example makes the following additional assumptions:

 
+ Request timestamp is `Fri, 24 May 2013 00:00:00 GMT`.
+ The bucket is in the US East (N. Virginia) region, and the credential `Scope` and the `Signing Key` calculations use `us-east-1` as the region specifier.  For more information, see [Regions and Endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the *AWS General Reference*. 

You can use this example as a test case to verify the signature that your code calculates; however, you must use the same bucket name, object key, time stamp, and the following example credentials:


| Parameter | Value | 
| --- | --- | 
| AWSAccessKeyId | AKIAIOSFODNN7EXAMPLE | 
| AWSSecretAccessKey | wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY | 

1. 

**StringToSign**

   1. 

**CanonicalRequest**

       

      ```
      GET
      /test.txt
      X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host
      host:examplebucket.s3.amazonaws.com
      
      host
      UNSIGNED-PAYLOAD
      ```

       

   1. 

**StringToSign**

       

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

       

1. 

**SigningKey**

    

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

    

1. 

**Signature**

    

   ```
   aeeed9bbccd4d02ee5c0109b86d86835f995330da4c265957d157751f604d404
   ```

    

   Now you have all information to construct a presigned URL. The resulting URL for this example is shown as follows (you can use this to compare your presigned URL):

   ```
   https://examplebucket.s3.amazonaws.com/test.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=aeeed9bbccd4d02ee5c0109b86d86835f995330da4c265957d157751f604d404
   ```

## Example 2


The following is an example (unrelated to the previous example) showing a presigned URL with the `X-Amz-Security-Token` parameter.

```
https://examplebucket.s3.us-east-1.amazonaws.com/test.txt
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request
&X-Amz-Date=20200524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host
&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEMv%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJGMEQCIBSUbVdj9YGs2g0HkHsOHFdkwOozjARSKHL987NhhOC8AiBPepRU1obMvIbGU0T%2BWphFPgK%2Fqpxaf5Snvm5M57XFkCqlAgjz%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8BEAAaDDQ3MjM4NTU0NDY2MCIM83pULBe5%2F%2BNm1GZBKvkBVslSaJVgwSef7SsoZCJlfJ56weYl3QCwEGr2F4BmCZZyFpmWEYzWnhNK1AnHMj5nkfKlKBx30XAT5PZGVrmq4Vkn9ewlXQy1Iu3QJRi9Tdod8Ef9%2FyajTaUGh76%2BF5u5a4O115jwultOQiKomVwO318CO4l8lv%2F3HhMOkpdanMXn%2B4PY8lvM8RgnzSu90jOUpGXEOAo%2F6G8OqlMim3%2BZmaQmasn4VYRvESEd7O72QGZ3%2BvDnDVnss0lSYjlv8PP7IujnvhZRnj0WoeOyMe1lL0wTG%2Fa9usH5hE52w%2FYUJccOn0OaZuyROuVsRV4Q70sbWQhUvYUt%2B0tUMKzm8vsFOp4BaNZFqobbjtb36Y92v%2Bx5kY6i0s8QE886jJtUWMP5ldMziClGx3p0mN5dzsYlM3GyiJ%2FO1mWkPQDwg3mtSpOA9oeeuAMPTA7qMqy9RNuTKBDSx9EW27wvPzBum3SJhEfxv48euadKgrIX3Z79ruQFSQOc9LUrDjR%2B4SoWAJqK%2BGX8Q3vPSjsLxhqhEMWd6U4TXcM7ku3gxMbzqfT8NDg%3D
&X-Amz-Signature=<signature-value>
```

# Examples: Signature Calculations in AWS Signature Version 4
Examples: Signature Calculations

**Topics**
+ [

## Signature Calculation Examples Using Java (AWS Signature Version 4)
](#sig-v4-examples-using-sdk-java)
+ [

## Examples of Signature Calculations Using C\$1 (AWS Signature Version 4)
](#sig-v4-examples-using-sdk-dotnet)

 For authenticated requests, unless you are using the AWS SDKs, you have to write code to calculate signatures that provide authentication information in your requests. Signature calculation in AWS Signature Version 4 (see [Authenticating Requests (AWS Signature Version 4)](sig-v4-authenticating-requests.md)) can be a complex undertaking, and we recommend that you use the AWS SDKs whenever possible. 

 This section provides examples of signature calculations written in Java and C\$1. The code samples send the following requests and use the HTTP Authorization header to provide authentication information:
+ **PUT object** – Separate examples illustrate both uploading the full payload at once and uploading the payload in chunks. For information about using the Authorization header for authentication, see [Authenticating Requests: Using the Authorization Header (AWS Signature Version 4)](sigv4-auth-using-authorization-header.md).
+ **GET object** – This example generates a presigned URL to get an object. Query parameters provide the signature and other authentication information. Users can paste a presigned URL in their browser to retrieve the object, or you can use the URL to create a clickable link. For information about using query parameters for authentication, see [Authenticating Requests: Using Query Parameters (AWS Signature Version 4)](sigv4-query-string-auth.md). 

The rest of this section describes the examples in Java and C\$1. The topics include instructions for downloading the samples and for executing them.

## Signature Calculation Examples Using Java (AWS Signature Version 4)
Signature Calculation Examples Using Java

The Java sample that shows signature calculation can be downloaded at [https://docs.aws.amazon.com/AmazonS3/latest/API/samples/AWSS3SigV4JavaSamples.zip](samples/AWSS3SigV4JavaSamples.zip). Note that these samples use AWS SDK for Java v1, and we recommend using [AWS SDK for Java v2](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html) for new applications. In `RunAllSamples.java`, the `main()` function executes sample requests to create an object, retrieve an object, and create a presigned URL for the object. The sample creates an object from the text string provided in the code:

```
PutS3ObjectSample.putS3Object(bucketName, regionName, awsAccessKey, awsSecretKey); 
GetS3ObjectSample.getS3Object(bucketName, regionName, awsAccessKey, awsSecretKey); 
PresignedUrlSample.getPresignedUrlToS3Object(bucketName, regionName, awsAccessKey, awsSecretKey); 
PutS3ObjectChunkedSample.putS3ObjectChunked(bucketName, regionName, awsAccessKey, awsSecretKey);
```

**To test the examples on a Linux-based computer**

The following instructions are for the Linux operating system.

1. In a terminal, navigate to the directory that contains `AWSS3SigV4JavaSamples.zip`.

1. Extract the .zip file. 

1. In a text editor, open the file `./com/amazonaws/services/s3/samples/RunAllSamples.java`. Update code with the following information:

    
   + The name of a bucket where the new object can be created. 

      
**Note**  
The examples use a virtual-hosted style request to access the bucket. To avoid potential errors, ensure that your bucket name conforms to the bucket naming rules as explained in [Bucket Restrictions and Limitations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/BucketRestrictions.html) in the *Amazon Simple Storage Service User Guide*.
   + AWS Region where the bucket resides. 

      If bucket is in the US East (N. Virginia) region, use us-east-1 to specify the region. For a list of other AWS Regions, go to [Amazon Simple Storage Service (S3)](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the *AWS General Reference*. 

1. Compile the source code and store the compiled classes into the `bin/` directory.

   ```
   javac -d bin -source 6 -verbose com
   ```

1. Change the directory to `bin/`, and then run `RunAllSamples`.

    

   ```
   java com.amazonaws.services.s3.sample.RunAllSamples
   ```

   The code runs all the methods in `main()`. For each request, the output will show the canonical request, the string to sign, and the signature.



## Examples of Signature Calculations Using C\$1 (AWS Signature Version 4)
Signature Calculation Examples Using C\$1

 The C\$1 sample that shows signature calculation can be downloaded at [https://docs.aws.amazon.com/AmazonS3/latest/API/samples/AmazonS3SigV4\$1Samples\$1CSharp.zip](samples/AmazonS3SigV4_Samples_CSharp.zip). Note that these samples use AWS SDK for .NET v1, and we recommend using [AWS SDK for .NET v3](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/home.html) for new applications. In `Program.cs`, the `main()` function executes sample requests to create an object, retrieve an object, and create a presigned URL for the object. The code for signature calculation is in the `\Signers` folder. 

```
PutS3ObjectSample.Run(awsRegion, bucketName, "MySampleFile.txt");

Console.WriteLine("\n\n************************************************");
PutS3ObjectChunkedSample.Run(awsRegion, bucketName, "MySampleFileChunked.txt");

Console.WriteLine("\n\n************************************************");
GetS3ObjectSample.Run(awsRegion, bucketName, "MySampleFile.txt");

Console.WriteLine("\n\n************************************************");
PresignedUrlSample.Run(awsRegion, bucketName, "MySampleFile.txt");
```

**To test the examples with Microsoft Visual Studio 2010 or later**

1. Extract the .zip file.

1.  Start Visual Studio, and then open the .sln file.

1. Update the App.config file with valid security credentials.

1. Update the code as follows:

    
   +  In `Program.cs`, provide the bucket name and the AWS Region where the bucket resides. The sample creates an object in this bucket.

1. Run the code.

1.  To verify that the object was created, copy the presigned URL that the program creates, and then paste it in a browser window. 

# Authenticating Requests: Browser-Based Uploads Using POST (AWS Signature Version 4)
Authenticating HTTP POST Requests

Amazon S3 supports HTTP POST requests so that users can upload content directly to Amazon S3. Using HTTP POST to upload content simplifies uploads and reduces upload latency where users upload data to store in Amazon S3. This section describes how you authenticate HTTP POST requests. For more information about HTTP POST requests, how to create a form, create a POST policy, and an example, see [Browser-Based Uploads Using POST (AWS Signature Version 4)](sigv4-UsingHTTPPOST.md).

To authenticate an HTTP POST request you do the following:

 

1. The form must include the following fields to provide signature and relevant information that Amazon S3 can use to re-calculate the signature upon receiving the request:    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html)

1. The POST policy must include the following elements:    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html)

1. For signature calculation the POST policy is the string to sign.

## Calculating a Signature


 The following diagram illustrates the signature calculation process. 

![\[Diagram showing AWS signature calculation process with StringToSign, SigningKey, and Signature steps.\]](http://docs.aws.amazon.com/AmazonS3/latest/API/images/sigV4-post.png)






**To Calculate a signature**

1. Create a policy using UTF-8 encoding.

1. Convert the UTF-8-encoded policy to Base64. The result is the string to sign.

1. Create the signature as an HMAC-SHA256 hash of the string to sign. You will provide the signing key as key to the hash function.

1. Encode the signature by using hex encoding.

For more information about creating HTML forms, security policies, and an example, see the following subtopics:


+ [Creating an HTML Form (Using AWS Signature Version 4)](sigv4-HTTPPOSTForms.md)
+ [POST Policy](sigv4-HTTPPOSTConstructPolicy.md)
+ [Example: Browser-Based Upload using HTTP POST (Using AWS Signature Version 4)](sigv4-post-example.md)

# Amazon S3 Signature Version 4 Authentication Specific Policy Keys


The following table shows the policy keys related Amazon S3 Signature Version 4 authentication that can be in Amazon S3 policies. In a bucket policy, you can add these conditions to enforce specific behavior when requests are authenticated by using Signature Version 4. For example policies, see [Bucket policy examples using Signature Version 4 related condition keys](#bucket-policy-sig-v4-condition-key-example). 


| Applicable Keys | Description | 
| --- | --- | 
| `s3:signatureversion` | Identifies the version of AWS Signature that you want to support for authenticated requests. For authenticated requests, Amazon S3 supports both Signature Version 4 and Signature Version 2. You can add this condition in your bucket policy to require a specific signature version. Valid values:  `"AWS"` identifies Signature Version 2   `"AWS4-HMAC-SHA256"` identifies Signature Version 4 | 
| `s3:authType` | Amazon S3 supports various methods of authentication (see [Authenticating Requests (AWS Signature Version 4)](sig-v4-authenticating-requests.md). You can optionally use this condition key to restrict incoming requests to use a specific authentication method. For example, you can allow only the HTTP `Authorization` header to be used in request authentication.  Valid values:  `REST-HEADER`  `REST-QUERY-STRING`  `POST`    | 
| `s3:signatureAge`  | The length of time, in milliseconds, that a signature is valid in an authenticated request. This condition works for: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AmazonS3/latest/API/bucket-policy-s3-sigv4-conditions.html) In Signature Version 2, this value is always set to 0.  In Signature Version 4, the signing key is valid for up to seven days. Therefore, the signatures are also valid for up to seven days. You can use this condition to further limit the signature age. For more information, see [Introduction to Signing Requests](sig-v4-authenticating-requests.md#signing-request-intro). Example value: `100`  | 
| `s3:x-amz-content-sha256`  |  You can use this condition key to disallow unsigned content in your bucket. When you use Signature Version 4, for requests that use the `Authorization` header, you add the `x-amz-content-sha256` header in the signature calculation and then set its value to the hash payload. Note that this condition key doesn't support the `x-amz-content-sha256` header as a query string parameter. You can use this condition key in your bucket policy to deny any uploads where payloads are not signed. For example, you can deny uploads that use the `Authorization` header to authenticate requests but don't sign the payload. For more information, see [Signature Calculations for the Authorization Header: Transferring Payload in a Single Chunk (AWS Signature Version 4)](sig-v4-header-based-auth.md). Valid value: `UNSIGNED-PAYLOAD`  | 

## Bucket policy examples using Signature Version 4 related condition keys


The following bucket policy denies any Amazon S3 presigned URL request on objects in `examplebucket` if the signature is more than ten minutes old. 

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
      {
         "Sid": "Deny a presigned URL request if the signature is more than 10 min old",
         "Effect": "Deny",
         "Principal": "*",
         "Action": "s3:*",
         "Resource": "arn:aws:s3:::examplebucket3/*",
         "Condition": {
            "NumericGreaterThan": {
               "s3:signatureAge": 600000
            }
         }
      }
   ]
}
```

------

The following bucket policy allows only requests that use the `Authorization` header for request authentication. Any POST or presigned URL requests will be denied.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
         {
               "Sid": "Allow only requests that use Authorization header for request authentication. Deny POST or presigned URL requests.",
               "Effect": "Deny",
               "Principal": "*",
               "Action": "s3:*",
               "Resource": "arn:aws:s3:::examplebucket3/*",
               "Condition": {
                     "StringNotEquals": {
                           "s3:authType": "REST-HEADER"
                     }
               }
         }
   ]
}
```

------

The following bucket policy denies requests that use presigned URLS for request authentication:

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Sid":"DenyUploadsUsingPresignedURL",
         "Effect":"Deny",
         "Principal":"*",
         "Action":"s3:*",
         "Resource":"arn:aws:s3:::amzn-s3-demo-bucket1/*",
         "Condition":{
            "StringEquals":{
               "s3:authType":"REST-query-string"
            }
         }
      }
   ]
}
```

------

The following bucket policy denies any uploads with unsigned payloads:

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
         {
               "Sid": "Deny uploads with unsigned payloads that use the Authorization header.",
               "Effect": "Deny",
               "Principal": "*",
               "Action": "s3:*",
               "Resource": "arn:aws:s3:::examplebucket3/*",
               "Condition": {
                     "StringEquals": {
                           "s3:x-amz-content-sha256": "UNSIGNED-PAYLOAD"
                     }
               }
         }
   ]
}
```

------