Skip to content

Instantly share code, notes, and snippets.

@VidyasagarMSC
Last active November 5, 2018 02:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save VidyasagarMSC/f7f5a3f36cc238d860a30cb00bdec542 to your computer and use it in GitHub Desktop.
Save VidyasagarMSC/f7f5a3f36cc238d860a30cb00bdec542 to your computer and use it in GitHub Desktop.
import datetime
import hashlib
import hmac
import requests
from requests.utils import quote
access_key = '<ACCESS_KEY>'
secret_key = '<SECRET_KEY>'
# request elements
http_method = 'GET'
region = '<REGION_NAME>' # us-south
bucket = '<BUCKET_NAME>'
cos_endpoint = '<ENDPOINT_WITHOUT_HTTPS>'
host = cos_endpoint
endpoint = 'https://' + host
object_key = '<OBJECT_NAME>'
expiration = 86400 # time in seconds
# hashing methods
def hash(key, msg):
return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()
# region is a wildcard value that takes the place of the AWS region value
# as COS doen't use regions like AWS, this parameter can accept any string
def createSignatureKey(key, datestamp, region, service):
keyDate = hash(('AWS4' + key).encode('utf-8'), datestamp)
keyRegion = hash(keyDate, region)
keyService = hash(keyRegion, service)
keySigning = hash(keyService, 'aws4_request')
return keySigning
# assemble the standardized request
time = datetime.datetime.utcnow()
timestamp = time.strftime('%Y%m%dT%H%M%SZ')
datestamp = time.strftime('%Y%m%d')
standardized_querystring = ('X-Amz-Algorithm=AWS4-HMAC-SHA256' +
'&X-Amz-Credential=' + access_key + '/' + datestamp + '/' + region + '/s3/aws4_request' +
'&X-Amz-Date=' + timestamp +
'&X-Amz-Expires=' + str(expiration) +
'&X-Amz-SignedHeaders=host')
standardized_querystring_url_encoded = quote(standardized_querystring, safe='&=')
standardized_resource = '/' + bucket + '/' + object_key
standardized_resource_url_encoded = quote(standardized_resource, safe='&')
payload_hash = 'UNSIGNED-PAYLOAD'
standardized_headers = 'host:' + host
signed_headers = 'host'
standardized_request = (http_method + '\n' +
standardized_resource + '\n' +
standardized_querystring_url_encoded + '\n' +
standardized_headers + '\n' +
'\n' +
signed_headers + '\n' +
payload_hash).encode('utf-8')
# assemble string-to-sign
hashing_algorithm = 'AWS4-HMAC-SHA256'
credential_scope = datestamp + '/' + region + '/' + 's3' + '/' + 'aws4_request'
sts = (hashing_algorithm + '\n' +
timestamp + '\n' +
credential_scope + '\n' +
hashlib.sha256(standardized_request).hexdigest())
# generate the signature
signature_key = createSignatureKey(secret_key, datestamp, region, 's3')
signature = hmac.new(signature_key,
(sts).encode('utf-8'),
hashlib.sha256).hexdigest()
# create and send the request
# the 'requests' package autmatically adds the required 'host' header
request_url = (endpoint + '/' +
bucket + '/' +
object_key + '?' +
standardized_querystring_url_encoded +
'&X-Amz-Signature=' +
signature)
print(('request_url: %s' % request_url))
print(('\nSending `%s` request to IBM COS -----------------------' % http_method))
print(('Request URL = ' + request_url))
request = requests.get(request_url)
print('\nResponse from IBM COS ---------------------------------')
print(('Response code: %d\n' % request.status_code))
print((request.text))
# this information can be helpful in troubleshooting, or to better
# understand what goes into signature creation
print('These are the values used to construct this request.')
print('Request details -----------------------------------------')
print(('http_method: %s' % http_method))
print(('host: %s' % host))
print(('region: %s' % region))
print(('endpoint: %s' % endpoint))
print(('bucket: %s' % bucket))
print(('object_key: %s' % object_key))
print(('timestamp: %s' % timestamp))
print(('datestamp: %s' % datestamp))
print('Standardized request details ----------------------------')
print(('standardized_resource: %s' % standardized_resource_url_encoded))
print(('standardized_querystring: %s' % standardized_querystring_url_encoded))
print(('standardized_headers: %s' % standardized_headers))
print(('signed_headers: %s' % signed_headers))
print(('payload_hash: %s' % payload_hash))
print(('standardized_request: %s' % standardized_request))
print('String-to-sign details ----------------------------------')
print(('credential_scope: %s' % credential_scope))
print(('string-to-sign: %s' % sts))
print(('signature_key: %s' % signature_key))
print(('signature: %s' % signature))
print('Because the signature key has non-ASCII characters, it is')
print('necessary to create a hexadecimal digest for the purposes')
print('of checking against this example.')
def hex_hash(key, msg):
return hmac.new(b'key', msg.encode('utf-8'), hashlib.sha256).hexdigest()
def createHexSignatureKey(key, datestamp, region, service):
keyDate = hex_hash(('AWS4' + key).encode('utf-8'), datestamp)
keyRegion = hex_hash(keyDate, region)
keyService = hex_hash(keyRegion, service)
keySigning = hex_hash(keyService, 'aws4_request')
return keySigning
signature_key_hex = createHexSignatureKey(secret_key, datestamp, region, 's3')
print(('signature_key (hexidecimal): %s' % signature_key_hex))
print('Header details ------------------------------------------')
print(('pre-signed url: %s' % request_url))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment