Python Generated Signature for S3 Post

2024/9/8 9:05:52

I think I've read nearly everything there is to read on base-64 encoding of a signature for in-browser, form-based post to S3: old docs and new docs. For instance:

http://doc.s3.amazonaws.com/proposals/post.html

And even found this:

http://s3.amazonaws.com/doc/s3-example-code/post/post_sample.html

Rather than using the above or Amazon's newer policy generator, or fiddle around with Boto, I'm trying to draft a simpler .py script that pulls the policy JSON from a plaintext file (policy.txt), and then generates the necessary base-64 encoded signature to help me draft the HTML form.

The signature itself (which is reliant on the encoded policy) is NOT being encoded correctly...maybe due to some sort of utf-8 vs. ascii or \n (newline) issue?

The script I'm working with is below, the policy and the AWS Secret Key private_key are from an AWS test case I'm using to see if this script works. The correctly encoded signature--as quoted by Amazon--is included in the script below for reference.

Can anyone tell me why the signature as calculated below does not match the reference signature provided by Amazon?:

In other words:

Why this is correctly encoded:

policy_encoded = base64.b64encode(policy)

but this one is NOT:

signature = base64.b64encode(hmac.new(private_key, policy_encoded, sha).digest())

PYTHON signature calculator...

#!/usr/bin/env python
# -*- coding: utf-8 -*-import base64, hmac, sha
from sys import argvscript, policy = argvprivate_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 (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", ""]
]
}
Answer

I think this is down to the contents of your policy.txt file.

I took the policy from the referenced link (http://doc.s3.amazonaws.com/proposals/post.html) and saved it as 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", ""],]
}

In order to get the exact same signature, this file must have the exact same contents.

For reference, when I copied and pasted: MD5 (policy.txt) = 5bce89d9ff799e2064c136d76bc7fc7a

If I use the following script (same as yours, just adjust filename and remove args)

#!/usr/bin/env python
# -*- coding: utf-8 -*-import base64, hmac, shaprivate_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="

Output I get:

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=

So, your code works, I just think you're signing a slightly different policy (whitespace differences)

https://en.xdnf.cn/q/72241.html

Related Q&A

Bringing a classifier to production

Ive saved my classifier pipeline using joblib: vec = TfidfVectorizer(sublinear_tf=True, max_df=0.5, ngram_range=(1, 3)) pac_clf = PassiveAggressiveClassifier(C=1) vec_clf = Pipeline([(vectorizer, vec)…

how to count the frequency of letters in text excluding whitespace and numbers? [duplicate]

This question already has answers here:Using a dictionary to count the items in a list(10 answers)Closed last year.Use a dictionary to count the frequency of letters in the input string. Only letters s…

Fastest algorithm for finding overlap between two very large lists?

Im trying to build an algorithm in Python to filter a large block of RDF data. I have one list consisting of about 70 thousand items formatted like <"datum">.I then have about 6GB worth…

Call Postgres SQL stored procedure From Django

I am working on a Django Project with a Postgres SQL Database. I have written a stored procedure that runs perfectly on Postgres.Now I want to call that stored procedure from Django 1.5 .. I have writt…

How can I mix decorators with the @contextmanager decorator?

Here is the code Im working with:from contextlib import contextmanager from functools import wraps class with_report_status(object):def __init__(self, message):self.message = messagedef __call__(self, …

supervisord always returns exit status 127 at WebFaction

I keep getting the following errors from supervisord at webFaction when tailing the log:INFO exited: my_app (exit status 127; not expected) INFO gave up: my_app entered FATAL state, too many start retr…

One dimensional Mahalanobis Distance in Python

Ive been trying to validate my code to calculate Mahalanobis distance written in Python (and double check to compare the result in OpenCV) My data points are of 1 dimension each (5 rows x 1 column). I…

DeprecationWarning: please use dns.resolver.Resolver.resolve()

I am using resolver() as an alternative to socket() as I found that when multiple connections are made to different IPs it ends up stopping working. Anyway it returns a warning to me that I should use …

python cannot find module when using ssh

Im using python on servers. When I run a python command which needs numpy module, if I do ssh <server name> <python command>that server will complain no module named numpy found.However, if…

Python sklearn installation windows

When trying to install Pythons sklearn package on Windows 10 using pip I am given an EnvironmentError that tells me there is no such file or directory of a specific file: ERROR: Could not install packa…