Amazon Web Services
General Reference (Version 1.0)

Signature Version 2 Signing Process

You can use Signature Version 2 to sign AWS Query API requests.

Supported Regions and Services

The following regions do not support Signature Version 2, regardless of which service you're using:

  • China (Beijing)

  • EU (Frankfurt)

For these regions, you must use Signature Version 4 to sign AWS Query API requests.

The following services currently support Signature Version 2 in all other regions.

AWS services that support Signature Version 2

Auto Scaling

Auto Scaling API Reference

AWS CloudFormation

AWS CloudFormation API Reference

Amazon CloudWatch

Amazon CloudWatch API Reference

AWS Elastic Beanstalk

Elastic Beanstalk API Reference

Amazon Elastic Compute Cloud

Amazon EC2 API Reference

Elastic Load Balancing

Elastic Load Balancing API Reference

Amazon Elastic MapReduce

Amazon Elastic MapReduce API Reference

Amazon ElastiCache

Amazon ElastiCache API Reference

AWS Identity and Access Management

IAM API Reference

AWS Import/Export

AWS Import/Export API Reference

Amazon Relational Database Service

Amazon Relational Database Service API Reference

Amazon Simple Notification Service

Amazon Simple Notification Service API Reference

Amazon Simple Queue Service

Amazon Simple Queue Service API Reference

Amazon SimpleDB

Amazon SimpleDB API Reference

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. For the list of endpoints for each service, see Regions and Endpoints.


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 Elastic MapReduce 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.
&Signature=calculated value

How to Generate a Signature Version 2 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.

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. For more information, see Using Temporary Security Credentials with APIs.

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 in ASCII order. 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 Elastic MapReduce API.


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 (Signature Version 2)

  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.


      The query string components would be reorganized as the following:

    3. Separate parameter names from their values with the equal sign character (=) (ASCII character 61), even if the value is empty. Separate parameter and value pairs with the ampersand character (&) (ASCII code 38). 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.


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:

  • Sample secret key:


The resulting signature must be base-64 encoded and then URI encoded.


Add the resulting value to the query request as a Signature parameter. You can use the signed request in an HTTP or HTTPS call.

For more information, see the following resources:

Troubleshooting Request Signatures Version 2

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="">
    <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>

IncompleteSignature Signing Error in a web service

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

<ErrorResponse xmlns="">
    <Message>Request must contain a signature that conforms to AWS standards</Message>

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 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)
        String result;
        try {

            // Get an hmac_sha256 key from the raw key bytes.
            SecretKeySpec signingKey = new SecretKeySpec(key.getBytes("UTF8"), HMAC_SHA256_ALGORITHM);

            // Get an hmac_sha256 Mac instance and initialize with the signing key.
            Mac mac = Mac.getInstance(HMAC_SHA256_ALGORITHM);

            // Compute the hmac on input data bytes.
            byte[] rawHmac = mac.doFinal(data.getBytes("UTF8"));

            // 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;