Signature Version 2 signing process - AWS General Reference

Signature Version 2 signing process


The AWS SDKs, AWS Command Line Interface (AWS CLI), and other AWS tools sign API requests for you using the access key that you specify when you configure the tool. When you use these tools, you don’t need to learn how to sign API requests. The following documentation explains how to sign API requests, but is only useful if you’re writing your own code to send and sign AWS API requests. We recommend that you use the AWS SDKs or other AWS tools to send API requests, instead of writing your own code.

If you must write your own code to sign AWS API requests, use Signature Version 4 (SigV4).

Supported Regions and services

You can use Signature Version 2 to sign API requests for some AWS services in some AWS Regions. Otherwise, you must use Signature Version 4 to sign API requests.

Regions that support Signature Version 2

  • US East (N. Virginia) Region

  • US West (N. California) Region

  • US West (Oregon) Region

  • Europe (Ireland) Region

  • Asia Pacific (Tokyo) Region

  • Asia Pacific (Singapore) Region

  • Asia Pacific (Sydney) Region

  • South America (São Paulo) Region

Services that support Signature Version 2

  • Amazon EC2 Auto Scaling

  • AWS CloudFormation

  • Amazon CloudWatch

  • AWS Elastic Beanstalk

  • Amazon Elastic Compute Cloud (Amazon EC2)

  • Elastic Load Balancing

  • Amazon EMR

  • Amazon ElastiCache

  • AWS Identity and Access Management (IAM)

  • AWS Import/Export

  • Amazon Relational Database Service (Amazon RDS)

  • Amazon Simple Notification Service (Amazon SNS)

  • Amazon Simple Queue Service (Amazon SQS)

  • Amazon SimpleDB

Services deprecating Signature Version 2

Components of a query request for Signature Version 2

AWS requires that each HTTP or HTTPS Query request formatted for Signature Version 2 contains the following:


Also known as the host part of an HTTP request. This is the DNS name of the computer where you send the Query request. This is different for each AWS Region.


The action you want a web service to perform. This value determines the parameters used in the request.


A value distributed by AWS when you sign up for an AWS account.


The hash-based protocol used to calculate the signature. This can be either HMAC-SHA1 or HMAC-SHA256 for Signature Version 2.


The version of the AWS signature protocol.


The time at which you make the request. Include this in the Query request to help prevent third parties from intercepting your request.

Required and optional parameters

Each action has a set of required and optional parameters that define the API call.


The calculated value that ensures the signature is valid and has not been tampered.

The following is an example Amazon EMR Query request formatted as an HTTPS GET request.

  • The endpoint,, is the default endpoint and maps to the Region us-east-1.

  • The action is DescribeJobFlows, which requests information about one or more job flows.


In the actual Query request, there are no spaces or newline characters. The request is a continuous line of text. The version below is formatted for human readability. &AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE &Action=DescribeJobFlows &SignatureMethod=HmacSHA256 &SignatureVersion=2 &Timestamp=2011-10-03T15%3A19%3A30 &Version=2009-03-31 &Signature=calculated value

How to generate a signature for a Query request

Web service requests are sent across the Internet and are vulnerable to tampering. To check that the request has not been altered, AWS calculates the signature to determine if any of the parameters or parameter values were changed en route. AWS requires a signature as part of every request.

Be sure to URI encode the request. For example, blank spaces in your request should be encoded as %20. Although an unencoded space is normally allowed by the HTTP protocol specification, unencoded characters create an invalid signature in your Query request. Do not encode spaces as a plus sign (+) as this will cause errors.

The following topics describe the steps needed to calculate a signature using AWS Signature Version 2.

Task 1: Format the Query request

Before you can sign the Query request, format the request in a standardized (canonical) format. This is needed because the different ways to format a Query request will result in different HMAC signatures. Format the request in a canonical format before signing. This ensures your application and AWS will calculate the same signature for a request.

To create the string to sign, you concatenate the Query request components. The following example generates the string to sign for the following call to the Amazon EMR API. Action=DescribeJobFlows &Version=2009-03-31 &AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE &SignatureVersion=2 &SignatureMethod=HmacSHA256 &Timestamp=2011-10-03T15:19:30

In the preceding request, the last four parameters (AWSAccessKeyID through Timestamp) are called authentication parameters. They're required in every Signature Version 2 request. AWS uses them to identify who is sending the request and whether to grant the requested access.

To create the string to sign

  1. Start with the request method (either GET or POST), followed by a newline character. For human readability, the newline character is represented as \n.

  2. Add the HTTP host header (endpoint) in lowercase, followed by a newline character. The port information is omitted if it is the standard port for the protocol (port 80 for HTTP and port 443 for HTTPS), but included if it is a nonstandard port.\n
  3. Add the URL-encoded version of each path segment of the URI, which is everything between the HTTP host header to the question mark character (?) that begins the query string parameters, followed by a newline character. Don't encode the forward slash (/) that delimits each path segment.

    In this example, if the absolute path is empty, use a forward slash (/).

    1. Add the query string components, as UTF-8 characters which are URL encoded (hexadecimal characters must be uppercase). You do not encode the initial question mark character (?) in the request. For more information, see RFC 3986.

    2. Sort the query string components by byte order. Byte ordering is case sensitive. AWS sorts these components based on the raw bytes.

      For example, this is the original order for the query string components.

      Action=DescribeJobFlows Version=2009-03-31 AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE SignatureVersion=2 SignatureMethod=HmacSHA256 Timestamp=2011-10-03T15%3A19%3A30

      The query string components would be reorganized as the following:

      AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE Action=DescribeJobFlows SignatureMethod=HmacSHA256 SignatureVersion=2 Timestamp=2011-10-03T15%3A19%3A30 Version=2009-03-31
    3. Separate parameter names from their values with the equal sign character (=), even if the value is empty. Separate parameter and value pairs with the ampersand character (&). Concatenate the parameters and their values to make one long string with no spaces. Spaces within a parameter value are allowed, but must be URL encoded as %20. In the concatenated string, period characters (.) are not escaped. RFC 3986 considers the period character an unreserved character, so it is not URL encoded.


      RFC 3986 does not specify what happens with ASCII control characters, extended UTF-8 characters, and other characters reserved by RFC 1738. Since any values may be passed into a string value, these other characters should be percent encoded as %XY where X and Y are uppercase hex characters. Extended UTF-8 characters take the form %XY%ZA... (this handles multibytes).

    The following example shows the query string components, with the parameters concatenated with the ampersand character (&), and sorted by byte order.

  4. To construct the finished canonical request, combine all the components from each step. As shown, each component ends with a newline character.

    GET\n\n /\n AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Action=DescribeJobFlows&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2011-10-03T15%3A19%3A30&Version=2009-03-31

Task 2: Calculate the signature

After you've created the canonical string as described in Task 1: Format the Query request, calculate the signature by creating a hash-based message authentication code (HMAC) that uses either the HMAC-SHA1 or HMAC-SHA256 protocols. The HMAC-SHA256 is preferred.

In this example, the signature is calculated with the following canonical string and secret key as inputs to a keyed hash function:

  • Canonical query string:

    GET\n\n /\n AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Action=DescribeJobFlows&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2011-10-03T15%3A19%3A30&Version=2009-03-31
  • Sample secret key:


The resulting signature must be base-64 encoded.


Add the resulting value to the query request as a Signature parameter. When you add this parameter to the request, you must URI encode it just like any other parameter. You can use the signed request in an HTTP or HTTPS call.

You can use temporary security credentials provided by AWS Security Token Service (AWS STS) to sign a request. The process is the same as using long-term credentials, but requests require an additional parameter for the security token.

The following request uses a temporary access key ID and the SecurityToken parameter.

Example request with temporary security credentials ?Action=GetAttributes &AWSAccessKeyId=access-key-from-AWS Security Token Service &DomainName=MyDomain &ItemName=MyItem &SignatureVersion=2 &SignatureMethod=HmacSHA256 &Timestamp=2010-01-25T15%3A03%3A07-07%3A00 &Version=2009-04-15 &Signature=signature-calculated-using-the-temporary-access-key &SecurityToken=session-token

For more information, see the following resources:

  • The Amazon EMR Developer Guide has information about Amazon EMR API calls.

  • The API documentation for each service has information about requirements and specific parameters for an action.

  • The AWS SDKs offer functions to generate Query request signatures. To see an example using the AWS SDK for Java, see Using the Java SDK to sign a Query request.

Troubleshooting request signatures

This section describes some error codes you might see when you are initially developing code to generate the signature to sign Query requests.

SignatureDoesNotMatch signing error in a web service

The following error response is returned when a web service attempts to validate the request signature by recalculating the signature value and generates a value that does not match the signature you appended to the request. This can occur because the request was altered between the time you sent it and the time it reached a web service endpoint (which is what the signature is designed to detect) or because the signature was calculated improperly. A common cause of the following error message is not properly creating the string to sign, such as forgetting to URL-encode characters such as the colon (:) and the forward slash (/) in Amazon S3 bucket names.

<ErrorResponse xmlns=""> <Error> <Type>Sender</Type> <Code>SignatureDoesNotMatch</Code> <Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.</Message> </Error> <RequestId>7589637b-e4b0-11e0-95d9-639f87241c66</RequestId> </ErrorResponse>

IncompleteSignature signing error in a web service

The following error indicates that signature is missing information or has been improperly formed.

<ErrorResponse xmlns=""> <Error> <Type>Sender</Type> <Code>IncompleteSignature</Code> <Message>Request must contain a signature that conforms to AWS standards</Message> </Error> <RequestId>7146d0dd-e48e-11e0-a276-bd10ea0cbb74</RequestId> </ErrorResponse>

Using the Java SDK to sign a Query request

The following example uses the amazon.webservices.common package of the AWS SDK for Java to generate an AWS Signature Version 2 Query request signature. To do so, it creates an RFC 2104-compliant HMAC signature. For more information about HMAC, see HMAC: Keyed-Hashing for Message Authentication.


Java is used as an example implementation. You can use the programming language of your choice to implement the HMAC algorithm to sign Query requests.

import; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import com.amazonaws.util.*; /** * This class defines common routines for generating * authentication signatures for AWS Platform requests. */ public class Signature { private static final String HMAC_SHA256_ALGORITHM = "HmacSHA256"; /** * Computes RFC 2104-compliant HMAC signature. * * @param data * The signed data. * @param key * The signing key. * @return * The Base64-encoded RFC 2104-compliant HMAC signature. * @throws * when signature generation fails */ public static String calculateRFC2104HMAC(String data, String key) throws { String result; try { // Get an hmac_sha256 key from the raw key bytes. SecretKeySpec signingKey = new SecretKeySpec(key.getBytes("UTF-8"), HMAC_SHA256_ALGORITHM); // Get an hmac_sha256 Mac instance and initialize with the signing key. Mac mac = Mac.getInstance(HMAC_SHA256_ALGORITHM); mac.init(signingKey); // Compute the hmac on input data bytes. byte[] rawHmac = mac.doFinal(data.getBytes("UTF-8")); // Base64-encode the hmac by using the utility in the SDK result = BinaryUtils.toBase64(rawHmac); } catch (Exception e) { throw new SignatureException("Failed to generate HMAC : " + e.getMessage()); } return result; } }