HMAC-SHA1 Signature

When accessing Amazon SimpleDB using SOAP (without using WS-Security) or REST, you must provide the following items so the request can be authenticated:

Following is the series of tasks required to authenticate requests to AWS using an HMAC-SHA1 request signature. It is assumed you have already created an AWS account and received an Access Key ID and Secret Access Key. For more information about those, see Creating an AWS Account and Your AWS Identifiers.

You perform the first three tasks.

HMAC-SHA1 Authentication Process

AWS performs the next three tasks.

HMAC-SHA1 Authentication Process

The procedure for creating the HMAC-SHA1 signature varies based on the API you're using. See the API-specific authentication topic for instructions on how to create the signature:

The time stamp (or expiration time) you use in the request must be a dateTime object, with the complete date plus hours, minutes, and seconds (for more information, go to http://www.w3.org/TR/xmlschema-2/#dateTime). For example: 2007-01-31T23:59:59Z. Although it is not required, we recommend you provide the time stamp in the Coordinated Universal Time (Greenwich Mean Time) time zone.

If you specify a time stamp (instead of an expiration time), the request automatically expires 15 minutes after the time stamp (in other words, AWS does not process a request if the request time stamp is more than 15 minutes earlier than the current time on AWS servers). Make sure your server's time is set correctly.

[Important]Important

If you are using .NET you must not send overly specific time stamps, due to different interpretations of how extra time precision should be dropped. To avoid overly specific time stamps, manually construct dateTime objects with no more than millisecond precision.

HMAC-SHA1 request signatures must be base64 encoded. The following Java sample code shows how to perform base64 encoding.

package amazon.webservices.common;
 /**
 * This class defines common routines for encoding * data in AWS Platform requests.
 */
 public class Encoding {
 /**
 * Performs base64-encoding of input bytes.
 *
 * @param rawData * Array of bytes to be encoded.
 * @return * The base64 encoded string representation of rawData.
 */
 public static String EncodeBase64(byte[] rawData) {
 return Base64.encodeBytes(rawData);
 }
 }

The following Java code sample shows how to calculate an HMAC request signature.

package amazon.webservices.common;

 import java.security.SignatureException;
 import javax.crypto.Mac;
 import javax.crypto.spec.SecretKeySpec;

 /**
 * This class defines common routines for generating
 * authentication signatures for AWS Platform requests.
 */
 public class Signature {
 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 = Encoding.EncodeBase64(rawHmac);

 } catch (Exception e) {
 throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
 }
 return result;
 }
 }