Request authentication is the process of verifying the identity of the sender of a request. In the context of Amazon Web Services (AWS) requests, authentication is the process by which AWS can verify that a request came from a registered user, as well as verify the identity of that registered user.
To enable authentication, each request must carry information about the identity of the request sender. The request must also contain additional information that AWS can use to verify that the request can only have been produced by the sender identified in the request. If the request passes this verification test it is determined to be "authentic" and AWS has sufficient information to verify the identity of the sender.
Verifying the identity of the sender of a request is important, as it ensures that only those requests made by the person or party responsible for the AWS account specified in the request are accepted and allowed to interact with AWS services. In this manner, request authentication allows Amazon to track the usage of AWS services on a per request basis. This enables Amazon to charge and bill AWS subscribers for use of AWS paid (not free) services. Authentication identifiers are also used for authorization, or access control. Users of AWS Web services can set access control policies on service resources, such as a queue created with Amazon SQS or objects stored with Amazon S3. An access control policy is a set of permissions that allow or restrict access to a resource.
To access Amazon web services, you must first create an AWS account at http://aws.amazon.com. You'll be asked to provide a credit card or other payment method to cover any charges from usage of AWS services. From this account you can view your account activity, change your payment method, view usage reports, and manage your AWS account access identifiers.
AWS account access identifiers are values assigned to an AWS account and known only by the person responsible for that account. You use your aws account access identifiers in AWS requests for the purposes of authentication.
Each AWS account is assigned an Access Key ID and a corresponding Secret Access Key. You use the Secret Access Key with HMAC-SHA1 authentication.
You can alternatively use an X.509 certificate, which is self-identifying, for use with HMAC-SHA1 authentication. The X.509 certificates generated by AWS can be used only for authentication with AWS.
Note: | Your Access Key ID is also used to determine the AWS account for usage tracking billing. Access Identifiers should not be shared, as the AWS account associated with the Access Key ID provided in a request will be billed for that usage. |
Upon creating an AWS account, you are assigned an Access Key ID (AWSAccessKeyId) and a Secret Access Key. The Access Key ID, which is associated with the AWS account, is used in requests to identify the party responsible for the request. However, because an Access Key ID is sent as a request parameter, it is not secret and could be used by anyone sending a request to AWS.
To protect from impersonation, you must provide additional information that can be used to verify your identity and ensure that the request is legitimate. This additional information, a request signature that is an HMAC-SHA1 hash calculated using your Secret Access Key, demonstrates possession of a shared secret known only to AWS and the sender of the request. A Secret Access Key is a 40-character alphanumeric sequence generated by AWS.
Note: | Access Key Identifiers can be used to calculate HMAC-SHA1 request signatures in Query, REST, and SOAP requests. |
In SQS, you can choose to use X.509 certificates for authentication with SOAP requests rather than use the access key identifiers. X.509 certificates can be used only with SOAP. The certificate used can be one you already have, or you can generate a new certificate via the AWS portal (see the procedure below).
AWS uses X.509 certificates only as a convenient way to carry a public key. Rather than trusting a certificate authority, AWS relies on your login to the AWS portal to authenticate you and bind you to the certificate. This allows you to avoid the expense and effort required to obtain a certificate from a commercial certificate authority. For this reason, we recommend you use a non-expiring, self-signed X.509 certificate for AWS.
When you upload your own certificate (see the procedure below), AWS confirms that the certificate has not expired. AWS does not determine if the certificate has been revoked, either by checking a certificate revocation list (CRL) or by any other means. AWS does not validate the certificate with a certificate authority or any trusted third parties and does not validate the chain of signing authorities contained in the certificate. AWS does not use or validate the distinguished name or other identifiers contained within the certificate.
Once you have uploaded your certificate, AWS performs no further checks when you use it. Certificate revocation or expiration will not invalidate your certificate for AWS use. To invalidate your certificate for AWS use, you must delete the certificate or replace it with a new certificate, either one you upload or one generated for you by AWS.
When using a certificate to authenticate SOAP requests, the following WS-Security standards must be observed:
ValueType should be one of the following:
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1
The EncodingType must be "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary". If it is different, the request will be rejected with a WS-Security InvalidSecurityToken fault.
To create a new X.509 certificate
Go to the Amazon Web Services web site at http://aws.amazon.com.
Point to the Your Web Services Account button to display a list of options.
Click View Access Key Identifiers, and when prompted, log in to your AWS account.
When the AWS Access Key Identifiers page is displayed, scroll down to the X.509 Certificate area of the page and click Create New.
Read the information on the Create a New Certificate page that is displayed, and click Yes to create your certificate.
From the Create Success page that is displayed, download your private key file and X.509 certificate file.
To upload your own X.509 certificate
Go to the Amazon Web Services web site at http://aws.amazon.com.
Point to the Your Web Services Account button to display a list of options.
Click View Access Key Identifiers, and when prompted, log in to your AWS account.
When the AWS Access Key Identifiers page is displayed, scroll down to the X.509 Certificate area of the page and click Upload.
Follow the instructions on the subsequent pages to upload your certificate.
Certificates generated via the AWS portal consist of two files: a certificate file and a private key file. The certificate files contain only the information necessary to use the certificate to generate signatures for requests to AWS. They do not contain any personal or company information, and are not registered with a Certificate Authority.
The contents of the generated certificate files are as follows:
Example
Certificate File, cert-XXX.pem (where XXXX represents the certificate value)
-----BEGIN CERTIFICATE----- <Base64 encoded DER certificate body> -----END CERTIFICATE-----
Private Key file, pk-XXX.pem
-----BEGIN PRIVATE KEY----- <Base64 encoded PKCS#8 private key> -----END PRIVATE KEY-----
Once you have downloaded the certificate files, you should store them to use with your IDE or toolkit as desired.
The following steps are the basic steps to authenticate requests to AWS. It is assumed you have already registered with AWS and received an Access Key ID and Secret Access Key.
You construct a request to AWS.
You use your Secret Access Key to calculate the request signature, a Keyed-Hashing for Message Authentication code (HMAC) with an SHA1 hash function, as defined in the next section of this topic.
You send the request data, the signature, and your Access Key ID 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 you used to calculate the signature in the request.
If the signature generated by AWS matches the one you sent in the request, the request is considered to be authentic. If the comparison fails, the request is discarded, and AWS returns an error response.
Every request to AWS for which authentication is required must contain a request signature. A request signature is calculated by constructing a string (based on the API being used - Query, SOAP, or REST) 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
When a request is received, AWS verifies that the request signature is valid by computing an HMAC-SHA1 hash for the request, and then comparing the value of that hash with the value included in the request. If the values match, the identity of the sender is verified and the request is accepted. If the values do not match, the request is rejected.
Note: | If a request contains a |
To calculate a signature for AWS requests
Based on the API (Query/SOAP/REST) being used, construct a string.
Compute an RFC 2104-compliant HMAC hash, 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. Below is a Java code sample to compute the signature from the string and the private key.
Example
import java.security.SignatureException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
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(rawData);
}
catch (Exception e) {
throw new SignatureException("Failed to generate HMAC : " + e.getMessage());
}
return result;
}