Python生成的S3 POST签名
我觉得我几乎看完了关于在浏览器中使用表单向S3发送的签名的base-64编码的所有资料,包括旧的和新的文档。例如:
http://doc.s3.amazonaws.com/proposals/post.html
我甚至还找到了这个:
http://s3.amazonaws.com/doc/s3-example-code/post/post_sample.html
与其使用上面的链接或亚马逊的新政策生成器,或者去折腾Boto,我想写一个简单的.py脚本,从一个文本文件(policy.txt)中提取政策的JSON,然后生成必要的base-64编码签名,以帮助我编写HTML表单。
但是,签名本身(依赖于编码后的政策)没有正确编码……可能是因为某种utf-8和ascii的区别,或者是\n(换行符)的问题?
我正在使用的脚本如下,政策和AWS的秘密密钥private_key
来自我用来测试这个脚本的AWS案例。亚马逊提供的正确编码的签名在下面的脚本中作为参考。
有没有人能告诉我,为什么下面计算出的签名与亚马逊提供的参考签名不匹配?
换句话说:
为什么这个是正确编码的:
policy_encoded = base64.b64encode(policy)
但这个却不是:
signature = base64.b64encode(hmac.new(private_key, policy_encoded, sha).digest())
PYTHON签名计算器……
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import base64, hmac, sha
from sys import argv
script, policy = argv
private_key = 'uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o'
input = open("..Desktop/policy.txt", "rb")
policy = input.read()
policy_encoded = base64.b64encode(policy)
signature = base64.b64encode(hmac.new(private_key, policy_encoded, sha).digest())
print "Your policy base-64 encoded is %s." % (policy_encoded)
print "Your signature base-64 encoded is %s." % (signature)
print "Your signature encoded should be 2qCp0odXe7A9IYyUVqn0w2adtCA="
JSON政策(policy.txt--UTF-8)
{ "expiration": "2007-12-01T12:00:00.000Z",
"conditions": [
{"bucket": "johnsmith"},
["starts-with", "$key", "user/eric/"],
{"acl": "public-read"},
{"success_action_redirect": "http://johnsmith.s3.amazonaws.com/successful_upload.html"},
["starts-with", "$Content-Type", "image/"],
{"x-amz-meta-uuid": "14365123651274"},
["starts-with", "$x-amz-meta-tag", ""]
]
}
1 个回答
我觉得问题出在你的policy.txt文件的内容上。
我从参考链接中获取了政策内容(http://doc.s3.amazonaws.com/proposals/post.html),然后把它保存为policy.txt。
{ "expiration": "2007-12-01T12:00:00.000Z",
"conditions": [
{"bucket": "johnsmith" },
["starts-with", "$key", "user/eric/"],
{"acl": "public-read" },
{"redirect": "http://johnsmith.s3.amazonaws.com/successful_upload.html" },
["starts-with", "$Content-Type", "image/"],
{"x-amz-meta-uuid": "14365123651274"},
["starts-with", "$x-amz-meta-tag", ""],
]
}
为了得到完全相同的签名,这个文件的内容必须完全一致。
作为参考,当我复制并粘贴时,得到的结果是:MD5 (policy.txt) = 5bce89d9ff799e2064c136d76bc7fc7a。
如果我使用以下脚本(和你的脚本一样,只是调整了文件名并去掉了args
)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import base64, hmac, sha
private_key = 'uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o'
input = open("policy.txt", "rb")
policy = input.read()
policy_encoded = base64.b64encode(policy)
signature = base64.b64encode(hmac.new(private_key, policy_encoded, sha).digest())
print "Your policy base-64 encoded is %s." % (policy_encoded)
print "Your signature base-64 encoded is %s." % (signature)
print "Your signature encoded should be 2qCp0odXe7A9IYyUVqn0w2adtCA="
我得到的输出是:
Your policy base-64 encoded is eyAiZXhwaXJhdGlvbiI6ICIyMDA3LTEyLTAxVDEyOjAwOjAwLjAwMFoiLAogICJjb25kaXRpb25zIjo gWwogICAgeyJidWNrZXQiOiAiam9obnNtaXRoIiB9LAogICAgWyJzdGFydHMtd2l0aCIsICIka2V5Ii wgInVzZXIvZXJpYy8iXSwKICAgIHsiYWNsIjogInB1YmxpYy1yZWFkIiB9LAogICAgeyJyZWRpcmVjd CI6ICJodHRwOi8vam9obnNtaXRoLnMzLmFtYXpvbmF3cy5jb20vc3VjY2Vzc2Z1bF91cGxvYWQuaHRt bCIgfSwKICAgIFsic3RhcnRzLXdpdGgiLCAiJENvbnRlbnQtVHlwZSIsICJpbWFnZS8iXSwKICAgIHs ieC1hbXotbWV0YS11dWlkIjogIjE0MzY1MTIzNjUxMjc0In0sCiAgICBbInN0YXJ0cy13aXRoIiwgIi R4LWFtei1tZXRhLXRhZyIsICIiXSwKICBdCn0K Your signature base-64 encoded is 2qCp0odXe7A9IYyUVqn0w2adtCA= Your signature encoded should be 2qCp0odXe7A9IYyUVqn0w2adtCA=
所以,你的代码是可以工作的,我只是觉得你签署的政策有点不同(可能是空格的差异)。