sigv4-post-example使用python

时间:2017-12-07 17:55:05

标签: python amazon-web-services amazon-s3 aws-cli

我正在尝试使用python,

http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html生成相同的签名
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()

但我的签名是cb0b0ec487fd5e01382c9c3b6b6a6dfa170da312ddab58a4b18869e7413951be,预期签名为46503978d3596de22955b4b18d6dfb1d54e8c5958727d5bdcd02cc1119c60fc9

我在哪里做错了?

注意

other_policy = b'''eyAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTMwVDEyOjAwOjAwLjAwMFoiLA0KICAiY29uZGl0aW9ucyI6IFsNCiAgICB7ImJ1Y2tldCI6ICJzaWd2NGV4YW1wbGVidWNrZXQifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAidXNlci91c2VyMS8iXSwNCiAgICB7ImFjbCI6ICJwdWJsaWMtcmVhZCJ9LA0KICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cDovL3NpZ3Y0ZXhhbXBsZWJ1Y2tldC5zMy5hbWF6b25hd3MuY29tL3N1Y2Nlc3NmdWxfdXBsb2FkLmh0bWwifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRDb250ZW50LVR5cGUiLCAiaW1hZ2UvIl0sDQogICAgeyJ4LWFtei1tZXRhLXV1aWQiOiAiMTQzNjUxMjM2NTEyNzQifSwNCiAgICB7IngtYW16LXNlcnZlci1zaWRlLWVuY3J5cHRpb24iOiAiQUVTMjU2In0sDQogICAgWyJzdGFydHMtd2l0aCIsICIkeC1hbXotbWV0YS10YWciLCAiIl0sDQoNCiAgICB7IngtYW16LWNyZWRlbnRpYWwiOiAiQUtJQUlPU0ZPRE5ON0VYQU1QTEUvMjAxNTEyMjkvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LA0KICAgIHsieC1hbXotYWxnb3JpdGhtIjogIkFXUzQtSE1BQy1TSEEyNTYifSwNCiAgICB7IngtYW16LWRhdGUiOiAiMjAxNTEyMjlUMDAwMDAwWiIgfQ0KICBdDQp9'''
来自http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html

1 个答案:

答案 0 :(得分:4)

代码中的错误

生成签名密钥的代码看起来很好。但是,在生成签名时,会切换参数。伪代码是:

Hex(HMAC-SHA256(SigningKey, StringToSign))

所以而不是

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

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

还是错?

这会产生以下签名,尽管有亚马逊文档,但我认为提供的base64字符串是正确的:

8afdbf4008c03f22c2cd3cdb72e4afbb1f6a588f3255ac628749a66d7f09699e

那么为什么亚马逊说签名应该是465039...c60fc9 ???

我很遗憾地说我不知道​​。我怀疑文档可能实际上是不准确的,无论是关于签名值还是关于用于生成它的输入参数值(密钥,日期,区域,服务,要签名的字符串)。

我觉得我有点想出这样的事情,但与此同时,我从经验中知道并非在线的每一篇技术文档都是100%准确的(即使是由信誉良好的来源)。

无论我尝试什么,我都无法重现这个签名。我看到成功产生此哈希的答案。

<强>证据

这里真的只有两件事:

  • 计算签名密钥。
  • 将其与“要签名的字符串”一起传递给散列函数,以生成签名。

您的代码使用"Deriving the Signing Key with Other Languages" here下的示例中的参数生成预期的签名密钥。这表明您正在正确计算签名密钥。 Python代码here

使用this example中的参数时,您的代码也会产生预期的签名。这表明您正在计算正确的签名密钥和正确的签名。 Python代码here

通过一些现有的Python代码运行您的问题中的参数,我知道这些代码可以处理多个服务(基于this),也会生成相同的8afdb...9699e签名。

我还扔了java signing code into an existing spring boot application,它也为输入参数生成了相同的8afdb...9699e签名。

该尝试什么?

我建议您假设您的签名代码是好的,并且此特定页面上的AWS文档是错误的。毕竟,您的代码可以与至少两个其他AWS示例一起使用。

使用您的凭据,您的存储桶政策,您的区域,当前日期,签署真实请求等等。

然后发布样本表格,看看它是否有效。如果它不起作用,您可以使用表单POST中的错误更新问题。

更新(7/15/2018)

AWS已更新其文档,this page现在包含正确的签名。出于历史目的,版本can be viewed here不正确。

有趣的是,该返回机器表明该页面至少在2017年6月23日之前是正确的。到7月14日它已经改为错误的签名,并且它至少至少直到12月19日, 2017年(超过5个月!)。