Uploading to Amazon S3 using cURL/libcurl Uploading to Amazon S3 using cURL/libcurl windows windows

Uploading to Amazon S3 using cURL/libcurl


You could execute a bash file. Here is an example upload.sh script which you could just run as: sh upload.sh yourfile

#!/bin/bashfile=$1bucket=YOUR_BUCKETresource="/${bucket}/${file}"contentType="application/x-itunes-ipa"dateValue=`date -R`stringToSign="PUT\n\n${contentType}\n${dateValue}\n${resource}"s3Key=YOUR_KEY_HEREs3Secret=YOUR_SECRETecho "SENDING TO S3"signature=`echo -en ${stringToSign} | openssl sha1 -hmac ${s3Secret} -binary | base64` curl -vv -X PUT -T "${file}" \ -H "Host: ${bucket}.s3.amazonaws.com" \ -H "Date: ${dateValue}" \ -H "Content-Type: ${contentType}" \ -H "Authorization: AWS ${s3Key}:${signature}" \ https://${bucket}.s3.amazonaws.com/${file}

more on: http://www.jamesransom.net/?p=58

http://www.jamesransom.net/?p=58


The game changed significantly since the question was asked, the simple authorization headers no longer apply, yet it is still feasible to perform with a UNIX shell script, as follows.

Ensure 'openssl' and 'curl' are available at the command line.

Beware, a single extra newline or space character, else the use of CRLF in place of the NewLine char alone would defeat the signature. Note too that you may want to use content types possibly with encodings to prevent any data transformation through the communication media. You may then have to adjust the list of signed headers at several places; please refer to AMAZON S3 API docs for the numerous conventions to keep enforced like alphabetical-lowercase ordering of header info used in hash calculations at several (redundant) places.

# BERHAUZ Nov 2019 - curl script for file upload to Amazon S3 Bucketstest -n "$1" || {  echo "usage: $0 <myFileToSend.txt>"  echo "... missing argument file ..."  exit}yyyymmdd=`date +%Y%m%d`isoDate=`date --utc +%Y%m%dT%H%M%SZ`# EDIT the next 4 variables to match your accounts3Bucket="myBucket.name.here"bucketLocation="eu-central-1" s3AccessKey="THISISMYACCESSKEY123"s3SecretKey="ThisIsMySecretKeyABCD1234efgh5678"#endpoint="${s3Bucket}.s3-${bucketLocation}.amazonaws.com"endpoint="s3-${bucketLocation}.amazonaws.com"fileName="$1"contentLength=`cat ${fileName} | wc -c`contentHash=`openssl sha -sha256 -hex ${fileName} | sed 's/.* //'`canonicalRequest="PUT\n/${s3Bucket}/${fileName}\n\ncontent-length:${contentLength}\nhost:${endpoint}\nx-amz-content-sha256:${contentHash}\nx-amz-date:${isoDate}\n\ncontent-length;host;x-amz-content-sha256;x-amz-date\n${contentHash}"canonicalRequestHash=`echo -en ${canonicalRequest} | openssl sha -sha256 -hex | sed 's/.* //'`stringToSign="AWS4-HMAC-SHA256\n${isoDate}\n${yyyymmdd}/${bucketLocation}/s3/aws4_request\n${canonicalRequestHash}"echo "----------------- canonicalRequest --------------------"echo -e ${canonicalRequest}echo "----------------- stringToSign --------------------"echo -e ${stringToSign}echo "-------------------------------------------------------"# calculate the signing keyDateKey=`echo -n "${yyyymmdd}" | openssl sha -sha256 -hex -hmac "AWS4${s3SecretKey}" | sed 's/.* //'`DateRegionKey=`echo -n "${bucketLocation}" | openssl sha -sha256 -hex -mac HMAC -macopt hexkey:${DateKey} | sed 's/.* //'`DateRegionServiceKey=`echo -n "s3" | openssl sha -sha256 -hex -mac HMAC -macopt hexkey:${DateRegionKey} | sed 's/.* //'`SigningKey=`echo -n "aws4_request" | openssl sha -sha256 -hex -mac HMAC -macopt hexkey:${DateRegionServiceKey} | sed 's/.* //'`# then, once more a HMAC for the signaturesignature=`echo -en ${stringToSign} | openssl sha -sha256 -hex -mac HMAC -macopt hexkey:${SigningKey} | sed 's/.* //'`authoriz="Authorization: AWS4-HMAC-SHA256 Credential=${s3AccessKey}/${yyyymmdd}/${bucketLocation}/s3/aws4_request, SignedHeaders=content-length;host;x-amz-content-sha256;x-amz-date, Signature=${signature}"curl -v -X PUT -T "${fileName}" \-H "Host: ${endpoint}" \-H "Content-Length: ${contentLength}" \-H "x-amz-date: ${isoDate}" \-H "x-amz-content-sha256: ${contentHash}" \-H "${authoriz}" \http://${endpoint}/${s3Bucket}/${fileName}

I must acknowledge that, for someone a bit involved in cryptography like me, the Amazon signature scheme deserves numerous critics:

  • there's much redundancy in the information being signed,
  • the 5 step HMAC cascade is almost inverting semantics between key seed and data where 1 step would suffice with proper usage and same security
  • the last 12 characters of the secret key are useless here, because the significant key length of a SHA256 HMAC is ... 256 bits, hence 32 bytes, of which the first 4 always start with "AWS4" for just no purpose.
  • overall AWS S3 API re-invents standards where a S/MIME payload would have done

Apologize for the critics, I was not able to resist. Yet acknowledge: it is working reliably, useful for many companies, and an interesting service with a rich API.


Solved: was missing an CURLOPT for the file size in my code and now everything is working perfectly