Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sigv4-post-example using python

I am trying to generate the same signature from http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html using python,

DateKey = hmac.new(b'AWS4wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY', b'20151229', hashlib.sha256).digest()

DateRegionKey = hmac.new(DateKey, b'us-east-1', hashlib.sha256).digest()

DateRegionServiceKey = hmac.new(DateRegionKey, b's3', hashlib.sha256).digest()

SigningKey = hmac.new(DateRegionServiceKey, b'aws4_request', hashlib.sha256).digest()

signature = hmac.new(other_policy, SigningKey, hashlib.sha256).hexdigest()

But my signature is cb0b0ec487fd5e01382c9c3b6b6a6dfa170da312ddab58a4b18869e7413951be and expected signature is 46503978d3596de22955b4b18d6dfb1d54e8c5958727d5bdcd02cc1119c60fc9

Where am I doing wrong ?

Note

other_policy = b'''eyAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTMwVDEyOjAwOjAwLjAwMFoiLA0KICAiY29uZGl0aW9ucyI6IFsNCiAgICB7ImJ1Y2tldCI6ICJzaWd2NGV4YW1wbGVidWNrZXQifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAidXNlci91c2VyMS8iXSwNCiAgICB7ImFjbCI6ICJwdWJsaWMtcmVhZCJ9LA0KICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cDovL3NpZ3Y0ZXhhbXBsZWJ1Y2tldC5zMy5hbWF6b25hd3MuY29tL3N1Y2Nlc3NmdWxfdXBsb2FkLmh0bWwifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRDb250ZW50LVR5cGUiLCAiaW1hZ2UvIl0sDQogICAgeyJ4LWFtei1tZXRhLXV1aWQiOiAiMTQzNjUxMjM2NTEyNzQifSwNCiAgICB7IngtYW16LXNlcnZlci1zaWRlLWVuY3J5cHRpb24iOiAiQUVTMjU2In0sDQogICAgWyJzdGFydHMtd2l0aCIsICIkeC1hbXotbWV0YS10YWciLCAiIl0sDQoNCiAgICB7IngtYW16LWNyZWRlbnRpYWwiOiAiQUtJQUlPU0ZPRE5ON0VYQU1QTEUvMjAxNTEyMjkvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LA0KICAgIHsieC1hbXotYWxnb3JpdGhtIjogIkFXUzQtSE1BQy1TSEEyNTYifSwNCiAgICB7IngtYW16LWRhdGUiOiAiMjAxNTEyMjlUMDAwMDAwWiIgfQ0KICBdDQp9'''

from the http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html

like image 225
dhana Avatar asked Dec 07 '17 17:12

dhana


1 Answers

Bug in the code

Your code to generate the signing key looks fine. However, when you generate the signature, the parameters are switched around. The pseudocode is:

Hex(HMAC-SHA256(SigningKey, StringToSign))

So instead of

signature = hmac.new(other_policy, SigningKey, hashlib.sha256).hexdigest()

you should have

signature = hmac.new(SigningKey, other_policy, hashlib.sha256).hexdigest()

Still wrong?

This produces the following signature, which despite the Amazon documentation, I believe is correct for the provided base64 string to sign:

8afdbf4008c03f22c2cd3cdb72e4afbb1f6a588f3255ac628749a66d7f09699e

So why does Amazon say the signature should be 465039...c60fc9???

I'm sorry to say I have no idea. I suspect the documentation may actually be inaccurate, either with respect to the signature value or with respect to the input parameter values used to generate it (secret key, date, region, service, string to sign).

I do feel like I'm going out on a limb a bit suggesting such a thing, but at the same time, I know from experience that not every piece of technical documentation online is 100% accurate (even when produced by a reputable source).

I couldn't reproduce this signature no matter what I tried. I'd love to see an answer that successfully produces this hash.

Evidence

There are really only two things going on here:

  • Calculate a signing key.
  • Pass it along with the "string to sign" to a hashing function, to generate the signature.

Your code produces the expected signing key using the parameters in the example under "Deriving the Signing Key with Other Languages" here. This suggests you're calculating the signing key correctly. Python code here.

Your code also produces the expected signature when using the parameters from this example. This suggests you're both calculating the correct signing key and the correct signature. Python code here.

Running the parameters from your question through some existing Python code that I know to work with several services (based on this) also produces the same 8afdb...9699e signature.

I also threw the java signing code into an existing spring boot application, and it also produces the same 8afdb...9699e signature for your input parameters.

What to try?

I suggest you assume your signing code is good, and the AWS documentation on this particular page is mistaken. After all, your code works fine with at least two other AWS examples.

Sign a real request, using your credentials, your bucket policy, your region, the current date, etc.

Then post the sample form and see if it works. If it doesn't work, you could update the question with the error you get from the form POST.

Update (7/15/2018)

AWS has updated their documentation, and this page now contains the correct signature. The incorrect version can be viewed here, for historical purposes.

Interestingly, the wayback machine suggests that the page was correct until at least June 23, 2017. By July 14 it had changed to the wrong signature, and it stayed incorrect at least until December 19, 2017 (over 5 months!).

like image 96
Mike Patrick Avatar answered Nov 05 '22 00:11

Mike Patrick