I am reading this document Authenticating Rest Requests

The first paragraph says ..

Every non-anonymous request to S3 must contain authentication information to establish the identity of the principal making the request. In REST, this is done by first putting the headers in a canonical format, then signing the headers using your AWS Secret Access Key.

There are two ways to send your signature with a request. The first is to put your AWS Access Key ID and the signature you computed into the Authorization header.

My 1st question is-

Is AWS Secret Access Key the same as AWS Access Key ID? if not the same, Where do I get the AWS Secret Access Key and AWS Access Key ID?

My 2nd question is about 'signature you computed'

I understand that this signature is computed like this -

String signatureYouComputed = base64(hmac-sha1(VERB + "\n" 
                                 + CONTENT-MD5 + "\n" 
                                 + CONTENT-TYPE + "\n" 
                                 + DATE + "\n" 
                                 + CanonicalizedAmzHeaders + "\n" 
                                 + CanonicalizedResource))

Here how do i get CONTENT-MD5, CanonicalizedAmzHeaders, and CanonicalizedResource?

I know these are basic questions for experienced integration developers but not for everyone. Please help me understand.

  • 1
    Right now, it looks like the assistance you need is specific to the AWS platform, not to the Salesforce platform. If that is not the case, could you please make an edit to clarify? Questions about AWS are not on topic here but would likely be on StackOverflow.
    – David Reed
    May 21 '19 at 15:06
  • This is for Salesforce. I am trying to Send a Request to an External System. This external system uses the same structure as AWS to autheticate requests from Salesforce. When I make a call to the external web service from salesforce, i need to send a signature with the request like this.. "Authorization: SFDC " + AccessKeyId + ":" + base64(hmac-sha1(VERB + "\n" + CONTENT-MD5 + "\n" + CONTENT-TYPE + "\n" + DATE + "\n" + CanonicalizedHeaders + "\n" + CanonicalizedResource)) May 21 '19 at 15:11
  • 1
    I recommend you go through the Apex Integration Services Module on Trailhead where authentication during REST calls is covered.
    – crmprogdev
    May 21 '19 at 15:56

I think this is both an AWS and SF question, but I think I can help. You're trying to Authenticate via HMAC. It depends on the SHA1 Algo and the Content-MD5 header that is later base64 encoded.

  1. Re: Keys/ Secrets: In AWS, Access keys consist of two parts: an access key ID (for example, AKIAIOSFODNN7EXAMPLE) and a secret access key (for example, wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY). This link will give you the docs on how to get both of them.
  2. RE: Computing the Signature: This code is pretty much what I use:
@future (callout=true)
public static void sendRequest(String jsonString){
    DateTime dtNow= System.Now();
    String dateFormat= dtNow.format('E, dd MMM yyyy kk:mm:ss z','GMT'); // date format as per the timezone of org
    HttpRequest req = new HttpRequest();
    req.setEndpoint(System.Label.EndPoint); // endpoint URL

    String strMd5= EncodingUtil.base64Encode (Crypto.generateDigest('MD5', Blob.valueOf(jsonString)));
    String strCanonical = 'application/json' + ',' + strMd5 + ',' + request URL + ',' +dateFormat;
    String strSignature = EncodingUtil.base64Encode(generateHmacSHA1Signature(strCanonical, system.label.Secret_Key));
    String authorizationHeader = system.label.APIAuth + ' ' + System.Label.Access_Id + ':' + strSignature;req.setMethod('POST');

    req.setHeader('ACCEPT',System.label.Accept_Header); // accept headers
    req.setHeader('Authorization', authorizationHeader); 
    req.setHeader('Content-Type', System.label.Content_Type); // content Type 
    Http http = new Http();

        HTTPResponse res = http.send(req);

public static blob generateHmacSHA1Signature(String canonical_str, String secreteKey){ 
    Blob mac = Crypto.generateMac('HMacSHA1', blob.valueof(canonical_str),blob.valueof(secreteKey)); 
    return mac;

I got it from this blog, and they gives some more info https://www.thinqloud.com/hmac-authentication-in-salesforce/

  • Thank you @ohana. I had seen the thinqloud article. It cleared some of my queries. In my use case, to be able to succesfully authenticate my request i have to follow the steps mentioned here s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html. I got lost along the way with CananicalizedHeaders and CanonicalizedResource. How do I create those ? What is the difference between Headers - i.e (content-md5, content-type, date, and anything that starts with x-amz) and CananicalizedHeaders ? May 21 '19 at 16:51
  • @user4947 the CanonicalizedAmzHeaders apply only headers that start with 'x-amz-' . At this point, I don't think you have to worry about it. The CanonicalizedResource is the URL for your resource on s3 that you're trying to access. This tells you how to build the url: docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html I think if you post these questions separately, you can get a more detailed response. May 21 '19 at 17:04
  • thank you for the documen for the suggestion of posting questions separately. I will do as suggested. May 21 '19 at 17:47
  • AWS v4 signature is supported out of the box in Summer '19 (going live in mid-June 2019) via NamedCredentials: releasenotes.docs.salesforce.com/en-us/summer19/release-notes/…
    – identigral
    May 21 '19 at 22:21

Not the answer you're looking for? Browse other questions tagged or ask your own question.