Signing S3 HTTP upload policies via the command line

When creating HTTP web forms to allow browser-based uploads to S3 bucket, you need to create and sign upload policies. Now if that statement lost you, then you should read over either of the following introductions to browser-based uploads to S3:

  1. Amazon Simple Storage Service: Browser-Based Uploads using POST Proposal (I'll be referring to this one a few times throughout this post)
  2. Browser Uploads to S3 using HTML POST Forms

Now, creating an upload policy quite straight forward, and covered in both links above. However, part of the process requires you to also sign the policy with your AWS secret key. This can be done many ways (indeed, the second link about shows examples for Ruby, Java and Python), but I wanted to be able to sign policies from the command line. This, it turns out, is quite easy using a recent version of openssl. It's done like this:

base64 -w0 policy.txt | openssl dgst -sha1 -hmac -binary | openssl base64

Easy, huh? Well, it did take me a little while to get the binary / base64 encodings just right. Also, the all important "-hmac" flag requires a recent version of openssl (0.9.8j is fine, but 0.9.8a is not).

So, here's an example using the policy document shown in the "Amazon Simple Storage Service: Browser-Based Uploads using POST Proposal" post. (Commands are in bold to aid readability.)

~]$ cat policy.txt
{ "expiration": "2007-12-01T12:00:00.000Z",
"conditions": [
{"bucket": "johnsmith" },
["starts-with", "$key", "user/eric/"],
{"acl": "public-read" },
{"redirect": "" },
["starts-with", "$Content-Type", "image/"],
{"x-amz-meta-uuid": "14365123651274"},
["starts-with", "$x-amz-meta-tag", ""],
~]$ base64 -w0 policy.txt
~]$ base64 -w0 policy.txt | openssl dgst -sha1 -hmac 'uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o' -binary | openssl base64

This process produces the exact same base64 encoded policy and policy signature that the original example arrived at - which is reassuring ;)

comments powered by Disqus