HTTP Query-based requests are HTTP requests that use the HTTP verb GET or POST and a Query parameter named Action or Operation. Action is used throughout this documentation, although Operation is supported for backward compatibility with other AWS Query APIs.
Query Parameters
Each Query request must include some common parameters to handle authentication and selection of an action. For more information, see Common Query Parameters.
Some operations take lists of parameters. These lists are
specified using the
param.
n
notation. Values of n
are
integers starting from 1.
Query API Authentication
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, go to http://www.faqs.org/rfcs/rfc2104.html.
The following are the basic steps used to authenticate requests to AWS. This assumes the developer is registered with AWS and has an Access Key ID and Secret Access Key.
Query Authentication Process
1 | The sender constructs a request to AWS. |
2 | 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. |
3 | 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. |
4 | AWS uses the Access Key ID to look up the Secret Access Key. |
5 | 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. |
6 | 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 |
Calculating the request signature
-
Based on the API (Query/SOAP/REST) you are using, construct a string.
-
Sort the query parameters (not URL-encoded) without using case-sensitively.
-
Concatenate the parameter names and values without the initial
?
or the separating&
and=
characters.
-
-
Compute an RFC 2104 compliant HMAC using the Secret AWS Access Key as the "key".
-
Convert the value to base64.
-
Include the value as the value of the
Signature
parameter in the request.
For example, the following is a Query string (line breaks added for clarity).
?Action=DescribeImages &AWSAccessKeyId=10QMXFEV71ZS32XQFTR2 &SignatureVersion=1 &Timestamp=2006-12-08T07%3A48%3A03Z &Version=2007-01-03
For the preceding Query string, you would calculate the HMAC signature over the following string.
ActionDescribeImagesAWSAccessKeyId10QMXFEV71ZS32XQFTR2SignatureVersion1Timestamp2006-12-08T07:48:03ZVersion2007-01-03
Using the preceding string and the secret key
eW91dHViZS5jb20vd2F0Y2g/dj1SU3NKMTlzeTNKSQ==
the base64 encoded
signature is as follows:
GjH3941IBe6qsgQu+k7FpCJjpnc=
The following 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 preceding example. |