Create a signed AWS API request
Important
If you use an AWS SDK (see Sample Code and
Libraries
In Regions that support multiple signature versions, manually signing requests means you must specify which signature version is used. When you supply requests to Multi-Region Access Points, SDKs and the CLI automatically switch to using Signature Version 4A without additional configuration.
You can use the AWS SigV4 signing protocol to create a signed request for AWS API requests.
-
Creating a canonical request based on the request details.
-
Calculating a signature using your AWS credentials.
-
Adding this signature to the request as an Authorization header.
AWS then replicates this process and verifies the signature, granting or denying access accordingly.
To see how you can use AWS SigV4 to sign API requests, see Request signature examples.
The following table describes the functions that are used in the process of creating a signed request. You need to implement code for these functions. For more information, see the code examples in the AWS SDKs.
| Function | Description |
|---|---|
|
|
Convert the string to lowercase. |
|
|
Lowercase base 16 encoding. |
|
|
Secure Hash Algorithm (SHA) cryptographic hash function. |
|
|
Computes HMAC by using the SHA256 algorithm with the signing key provided. This is the final signature when you sign with SigV4. |
|
|
Elliptic Curve Digital Signature Algorithm (ECDSA) signature computed by using asymmetric signatures based on public-private key cryptography. |
|
|
A NIST SP800-108 KDF in Counter Mode using the PRF function
HMAC-SHA256 as defined in NIST SP
800-108r1 |
|
|
An octet to integer function as described in ANSI X9.62. |
|
|
Remove any leading or trailing whitespace. |
|
|
URI encode every byte. UriEncode() must enforce the following rules:
ImportantThe standard UriEncode functions provided by your development platform might 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 make sure that your encoding will work. To see an example of a UriEncode function in Java, see Java Utilities |
Note
When signing your requests, you can use either AWS SigV4 or AWS SigV4a. The key difference between the two is determined by how the signature is calculated. With SigV4a, the region set is included in the string to sign, but is not part of the credential derivation step.
Signing requests with temporary security credentials
Instead of using long-term credentials to sign a request, you can use temporary security credentials provided by AWS Security Token Service (AWS STS).
When you use temporary security credentials, you must add
X-Amz-Security-Token to the Authorization header or include it in the
query string to hold the session token. Some services require that you add
X-Amz-Security-Token to the canonical request. Other services require
only that you add X-Amz-Security-Token at the end, after you calculate the
signature. Check the documentation for each AWS service for specific
requirements.
Summary of signing steps
Create a canonical request
Arrange the contents of your request (host, action, headers, etc.) into a standard canonical format. The canonical request is one of the inputs used to create the string to sign. For details on creating the canonical request, see Elements of an AWS API request signature.
Create a hash of the canonical request
Hash the canonical request using the same algorithm that you used to create the hash of the payload. The hash of the canonical request is a string of lowercase hexadecimal characters.
Create a string to sign
Create a string to sign with the canonical request and extra information such as the algorithm, request date, credential scope, and the hash of the canonical request.
Derive a signing key
Use the secret access key to derive the key used to sign the request.
Calculate the signature
Perform a keyed hash operation on the string to sign using the derived signing key as the hash key.
Add the signature to the request
Add the calculated signature to an HTTP header or to the query string of the request.
Create a canonical request
To create a canonical request, concatenate the following strings, separated by newline characters. This helps make sure that the signature that you calculate can match the signature that AWS calculates.
<HTTPMethod>\n<CanonicalURI>\n<CanonicalQueryString>\n<CanonicalHeaders>\n<SignedHeaders>\n<HashedPayload>
-
HTTPMethod– The HTTP method, such asGET,PUT,HEAD, andDELETE. -
CanonicalUri– The URI-encoded version of the absolute path component URI, 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. If the absolute path is empty, use a forward slash character (/). The URI in the following example,/amzn-s3-demo-bucket/myphoto.jpg, is the absolute path and you don't encode the/in the absolute path:http://s3.amazonaws.com/amzn-s3-demo-bucket/myphoto.jpg -
CanonicalQueryString– The URI-encoded query string parameters. You URI-encode each name and value 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:http://s3.amazonaws.com/amzn-s3-demo-bucket?prefix=somePrefix&marker=someMarker&max-keys=2The 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 theACLsubresource on theamzn-s3-demo-bucketbucket:http://s3.amazonaws.com/amzn-s3-demo-bucket?aclIn this case, the CanonicalQueryString would be:
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 newline character ("\n"). -
CanonicalHeaders– A list of request headers with their values. Individual header name and value pairs are separated by the newline character ("\n"). The following is an example of a CanonicalHeader:Lowercase(<HeaderName1>)+":"+Trim(<value>)+"\n" Lowercase(<HeaderName2>)+":"+Trim(<value>)+"\n" ... Lowercase(<HeaderNameN>)+":"+Trim(<value>)+"\n"CanonicalHeaders list must include the following:
-
HTTP
hostheader. -
If the
Content-Typeheader is present in the request, you must add it to theCanonicalHeaderslist. -
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 includex-amz-security-tokenin your request. You must add this header in the list ofCanonicalHeaders. -
For SigV4a, you must include a region set header that specifies the set of regions the request will be valid in. The header
X-Amz-Region-Setis specified as a list of comma separated values. The following example shows a region header that allows a request to be made in both us-east-1 and us-west-1 regions.X-Amz-Region-Set=us-east-1,us-west-1You can use wildcards (*) in regions to specify multiple regions. In the following example, the header allows a request to be made in both us-west-1 and us-west-2.
X-Amz-Region-Set=us-west-*
Note
-