Using the Query API
HTTP Query-based requests are defined as any HTTP requests using the HTTP verb GET or POST and a Query parameter named either Action or Operation. Action is used throughout this documentation, although Operation is supported for backward compatibility with other AWS Query APIs.
Each Query request must include some common parameters to handle authentication and selection of an action. These parameters are documented in the section called “Common Query Parameters”.
Some operations take lists of parameters. These lists are
specified using the
param.
n
notation. Values of n
should be
integers starting from 1.
Every request to Amazon EC2 must contain a request signature. A request signature is calculated by constructing a string and then calculating an RFC 2104-compliant HMAC-SHA1 hash, using the Secret AWS Access Key as the key. For more information, see http://www.faqs.org/rfcs/rfc2104.html.
The following are the basic steps used in authenticating requests to AWS. It is assumed that the developer has already registered with AWS and received an Access Key ID and Secret Access Key.
-
The sender constructs a request to AWS.
-
The sender calculates the request signature, a Keyed-Hashing for Message Authentication Code (HMAC) with a SHA-1 hash function, as defined in the next section of this topic.
-
The sender of the request sends the request data, the signature, and Access Key ID (the key-identifier of the Secret Access Key used) to AWS.
-
AWS uses the Access Key ID to look up the Secret Access Key.
-
AWS generates a signature from the request data and the Secret Access Key using the same algorithm used to calculate the signature in the request.
-
If the signatures match, the request is considered to be authentic. If the comparison fails, the request is discarded, and AWS returns an error response.
Note | |
---|---|
If a request contains a Timestamp parameter, the signature calculated for the request expires 15 minutes after the Timestamp value. If a request contains an Expires parameter, the signature expires at the time specified as the value for the Expires parameter. |
The following steps demonstrate how to calculate a signature for requests to AWS:
-
Based on the API (Query/SOAP/REST) being used, construct a string.
-
Compute an RFC 2104 compliant HMAC using the Secret AWS Access Key as the "key". This value should be base64 encoded, and then included as the value for the Signature parameter for the request.
The following steps demonstrate how to calculate the string to be signed:
-
The query parameters (not URL-encoded) need to be sorted case-insensitively.
-
Concatenate the parameter names and values without the initial
?
or the separating&
and=
characters.
Given the following Query string to sign (linebreaks added for clarity):
?Action=DescribeImages &AWSAccessKeyId=10QMXFEV71ZS32XQFTR2 &SignatureVersion=1 &Timestamp=2006-12-08T07%3A48%3A03Z &Version=2007-01-03
The HMAC signature should be calculated over the following string:
ActionDescribeImagesAWSAccessKeyId10QMXFEV71ZS32XQFTR2SignatureVersion1Timestamp2006-12-08T07:48:03ZVersion2007-01-03
Given the Query string above and the secret key
DMADSSfPfdaDjbK+RRUhS/aDrjsiZadgAUm8gRU2
the base64 encoded
signature is as follows:
GjH3941IBe6qsgQu+k7FpCJjpnc=
Shown below is a Java code sample to compute the signature from the string and the private key.
import java.security.SignatureException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; public class HmacExample { private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1"; /** * Computes RFC 2104-compliant HMAC signature. * * @param data * The data to be signed. * @param key * The signing key. * @return * The base64-encoded RFC 2104-compliant HMAC signature. * @throws * java.security.SignatureException when signature generation fails */ public static String calculateRFC2104HMAC(String data, String key) throws java.security.SignatureException { String result; try { // get an hmac_sha1 key from the raw key bytes SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM); // get an hmac_sha1 Mac instance and initialize with the signing key Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM); mac.init(signingKey); // compute the hmac on input data bytes byte[] rawHmac = mac.doFinal(data.getBytes()); // base64-encode the hmac result = Base64.encodeBytes(rawHmac); } catch (Exception e) { throw new SignatureException("Failed to generate HMAC : " + e.getMessage()); } return result; } }
Note | |
---|---|
You must import a base 64 encoder to perform the last step in the above method. |
Here is a complete example request, including all required parameters:
?AWSAccessKeyId=10QMXFEV71ZS32XQFTR2&Action=DescribeImages&SignatureVersion=1&Timestamp=2006-12-08T07%3A48%3A03Z&Version=2007-01-03&Signature=69DSJs1z%2B0wWJmdB77%2BLm0N0Trs%3D