Create multipart using S3 API

0

I have been trying to create a multipart upload using S3 API but I got stuck with signature verification. I am not sure if I am doing it in the right way but anyone who can give me a suggestion on it would be appreciated. Following is my code snippet. please have a look into it. reference (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html)

import datetime
import hashlib
import hmac
import os
import sys

import requests

method = 'POST'
service = 's3'
host = 's3_bucket_host'
region = 'aws_region'
endpoint = 'https://s3.us-east-1.amazonaws.com/'
request_parameters = 'uploads='


def sign(key, msg):
    return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()


def getSignatureKey(key, dateStamp, regionName, serviceName):
    kDate = sign(('AWS4' + key).encode('utf-8'), dateStamp)
    kRegion = sign(kDate, regionName)
    kService = sign(kRegion, serviceName)
    kSigning = sign(kService, 'aws4_request')
    return kSigning


access_key = os.environ.get('AWS_ACCESS_KEY_ID')
secret_key = os.environ.get('AWS_SECRET_ACCESS_KEY')

t = datetime.datetime.utcnow()
amzdate = t.strftime('%Y%m%dT%H%M%SZ')
print(amzdate)
datestamp = t.strftime('%Y%m%d')  # Date w/o time, used in credential scope

canonical_uri = 'xyz/xyz'

canonical_querystring = request_parameters

canonical_headers = 'host:' + host + '\n' + 'x-amz-date:' + amzdate + '\n' + 'x-amz-content-sha256:abcdefghijklmnopqrstuvwxyz'


signed_headers = 'host;x-amz-content-sha256;x-amz-date'

payload_hash = hashlib.sha256(('').encode('utf-8')).hexdigest()

canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash


algorithm = 'AWS4-HMAC-SHA256'
credential_scope = datestamp + '/' + region + '/' + service + '/' + 'aws4_request'
string_to_sign = algorithm + '\n' + amzdate + '\n' + credential_scope + '\n' + hashlib.sha256(
    canonical_request.encode('utf-8')).hexdigest()


signing_key = getSignatureKey(secret_key, datestamp, region, service)


signature = hmac.new(signing_key, string_to_sign.encode('utf-8'), hashlib.sha256).hexdigest()

authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature


print(authorization_header)
headers = {'x-amz-date': amzdate,
           'Authorization': authorization_header,
           'host': host,
           'x-amz-content-sha256': 'abcdefghijklmnopqrstuvwxyz'}


request_url = endpoint + canonical_uri + '?' + canonical_querystring
#
print('\nBEGIN REQUEST++++++++++++++++++++++++++++++++++++')
print('Request URL = ' + request_url)
r = requests.post(request_url, headers=headers)

print('\nRESPONSE++++++++++++++++++++++++++++++++++++')
print('Response code: %d\n' % r.status_code)
# from awsxmltojson import convert_xml_to_dict
print(r.text)


## response from API
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Error>

Jaydip
asked 2 years ago90 views
No Answers

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions