# -*- coding:utf-8 -*- # AWS Version 4 signing example # EC2 API (DescribeRegions) # See: http://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html # This version makes a GET request and passes the signature # in the Authorization header. import sys, os, base64, datetime, hashlib, hmac import requests # pip install requests access_key = 'xxxxxxxxxxxxxxxxxxxxxxxx' secret_key = 'SSSSSSSSSSSSSSSSSSSSSSSSSS' if access_key is None or secret_key is None: print ('No access key is available.') sys.exit() # ************* REQUEST VALUES ************* method = 'GET' service = 'kec' host = 'kec.cn-beijing-6.api.ksyun.com' region = 'cn-beijing-6' endpoint = 'https://kec.cn-beijing-6.api.ksyun.com' request_parameters = 'Action=DescribeInstances&Version=2016-03-04' #查询主机 body = '' # Key derivation functions. See: # http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-python 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 # Read AWS access key from env. variables or configuration file. Best practice is NOT # to embed credentials in code. #access_key = os.environ.get('AWS_ACCESS_KEY_ID') #secret_key = os.environ.get('AWS_SECRET_ACCESS_KEY') # Create a date for headers and the credential string t = datetime.datetime.utcnow() amzdate = t.strftime('%Y%m%dT%H%M%SZ') datestamp = t.strftime('%Y%m%d') # Date w/o time, used in credential scope # ************* TASK 1: CREATE A CANONICAL REQUEST ************* # http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html # Step 1 is to define the verb (GET, POST, etc.)--already done. # Step 2: Create canonical URI--the part of the URI from domain to query # string (use '/' if no path) canonical_uri = '/' # Step 3: Create the canonical query string. In this example (a GET request), # request parameters are in the query string. Query string values must # be URL-encoded (space=%20). The parameters must be sorted by name. # For this example, the query string is pre-formatted in the request_parameters variable. canonical_querystring = request_parameters # Step 4: Create the canonical headers and signed headers. Header names # must be trimmed and lowercase, and sorted in code point order from # low to high. Note that there is a trailing . canonical_headers = 'host:' + host + ' ' + 'x-amz-date:' + amzdate + ' ' # Step 5: Create the list of signed headers. This lists the headers # in the canonical_headers list, delimited with ";" and in alpha order. # Note: The request can include any headers; canonical_headers and # signed_headers lists those that you want to be included in the # hash of the request. "Host" and "x-amz-date" are always required. signed_headers = 'host;x-amz-date' # Step 6: Create payload hash (hash of the request body content). For GET # requests, the payload is an empty string (""). payload_hash = hashlib.sha256(body.encode()).hexdigest() #payload 指的是对body体的hash值 # Step 7: Combine elements to create canonical request canonical_request = method + ' ' + canonical_uri + ' ' + canonical_querystring + ' ' + canonical_headers + ' ' + signed_headers + ' ' + payload_hash print('