Problem calculating Signatures(aws) in Eliir

So I am going through the documenation of AWS in order to calculate Signature for the Authorization Header

and I am following through with code in Elixir but at some point something appartently goes terribly wrong but I can’t get what.

So working with the Example: GET Object section from (https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html#canonical-request)
in order to verify my process I have the following problem

  1. I have a function that returns the canonical request as explained in the page and works fine for me, when I add the attributes of the example I get back exactly what was expected

This is the string returned if printed to the console using the IO.write function

GET
/text.txt

host:examplebucket.s3.amazonaws.com
range:bytes=0-9
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date:20130524T000000Z

host;range;x-amz-content-sha256;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Which is exactly how it looks also in the example(nothing difficult so far just some minor string manipulation)

Next steps is to created the so called StringToSign
and the steps for calculating this one as explained in the aws web site is the following

“AWS4-HMAC-SHA256” + “\n” +
timeStampISO8601Format + “\n” +
<Scope> + “\n” +
Hex(SHA256Hash( <CanonicalRequest> ))

my code for calculating this is the following

def string_to_sign(path, headers, payload) do
    @authorization<> "\n"<>
    date_time_aws_8601() <> "\n" <> 
    scope() <> "\n"<>
    hex_sha_canonical_request(path, headers, payload)
  end 


  def canonical_request2(path, headers, payload) do
    """
    GET
    #{path}

    #{canonical_headers(headers)}
    
    #{signed_headers(headers)}
    #{hashed_payload(payload)}
    """
  end


def hex_sha_canonical_request(path, headers, payload) do
    can_req = canonical_request2(path, headers, payload)
    :crypto.hash(:sha256, can_req)
    |> Base.encode16
  end

then the result expected by the site looks like this

AWS4-HMAC-SHA256
20130524T000000Z
20130524/us-east-1/s3/aws4_request
9e0e90d9c76de8fa5b200d8c849cd5b8dc7a3be3951ddb7f6a76b4158342019d

But mine looks like this

AWS4-HMAC-SHA256
20130524T000000Z
20130524/us-east-1/s3/aws4_request
BFD7EE52C8FEBBBD70EA653DE76795FC415FB65C331ADC4DDD266E8C6369AD17

The problem apparently is that those look completly different but
I can’t understand how this is possible since my function for getting the canonical_request looks like it’s giving correct results and then the calculations do get the hex digits that do not match looks fairly straight forward

Hex(SHA256Hash(<CanonicalRequest>))

If anybody can understend where the problem could possible be please give me some direction because right now I can’t think what could have possible went wrong.

Double check that your line break matches AWS spec. Is it \n or \r\n, etc.

2 Likes

Thanks for the response, I tried either with the method above and with another method that looks like
the following so explicitly setting the newline characters in the string I don’t know how else to go with this do you have an idea of how else could I verify that ?

def canonical_request(path, headers, payload) do
    "GET\n" <>
      path <> "\n"<>
        ""<>"\n"<>
    canonical_headers(headers)<>"\n\n"<>
    signed_headers(headers)<>"\n"<>
    hashed_payload(payload)
  end

Oh. Are you sure you don’t need hmac-sha256?

:crypto.hmac/3

1 Like

Somewere along the way to insanity I figured that the copy to clipboard functionality of the of the AWS web site adds two additional spaces at the end of the text which as you might expect change the hash created by sha256 completly the thing is that although the copy to clipboard would add those to spaces this is probably a mistake becase as I figured later they were not included when the hash indicated underneath was calculated thus most of the confusion.

Thanks a lot all

2 Likes

thanks for the suggestion but as it turned out the algorithm invocation was the correct one.