I'm trying to upload files to Google Cloud Storage via a HTML Form via the POST method. Google states in their documentation that to assign a non-standard ACL you need both a policy and a signature field.
Reading through their descriptions on how to generate these values, it seems pretty simple. Unfortunately, after many attempts, I still cannot generate values that will pass Google's filters. I continuously get errors saying that my signature does not match the policy document.
Could someone instruct me where I'm going wrong? This is my process:
This is the easy part. My policy document is:
{"expiration": "2015-06-16T11:11:11Z",
"conditions": [
["starts-with", "$key", ""],
{"acl": "public-read" },
{"bucket": "publicjs"},
{"success_action_redirect": "http://localhost/gcs.php" }
] }
I then went to this website and encoded the above value in base64. This is what I'm using as my policy document.
Now for the signature. I need to encrypt my policy document using my secret key as the encryption key, so I went to this website to do the encryption. I entered my base64 encoded policy document (from step 2) into the main text area, and my interoperability "Secret" key into the key box.
Hit enter, and the value next to base64 should be the signature value.
Put values in form, send POST request, receive error.
Where am I going wrong?
The encoding sequence should be as follows:
base64 encode the policy document (let's call that the encoded policy)
generate a SHA1 hash (for interop keys only, use SHA256 if you want to use an RSA key) of the encoded policy and base64 encode that (let's call that the signature)
send the encoded policy and the signature in the form post request (along with rest of the form)
Here's an idealized implementation of the sequence in Python:
POLICY = '''{
"expiration": "2015-06-16T11:11:11Z",
"conditions": [
["starts-with", "$key", "test"],
{"acl" : "public-read"}
]
}'''
GEN_FORM = '''
<form action="%s" method="post" enctype="multipart/form-data">
<input type="hidden" name="acl" value="public-read">
<input type="hidden" name="bucket" value="YOUR_BUCKET">
<input type="hidden" name="key" value="YOUR_OBJECT_NAME">
<input type="hidden" name="GoogleAccessId" value="YOUR_ACCESS_ID">
<input type="hidden" name="policy" value="%s">
<input type="hidden" name="signature" value="%s">
<input name="file" type="file">
<input type="submit" value="Upload">
</form>
'''
encoded_policy = base64.b64encode(POLICY).strip()
h = hmac.new(YOUR_SECRET_KEY, digestmod=sha.sha)
h.update(encoded_policy)
signature = base64.b64encode(h.digest())
gen_html = GEN_FORM % (url, encoded_policy, signature)