获取临时令牌后将使用V4 signature签名字符串请求上传
"""
@File : AWSV4Signature.py
@Time : 2023/6/6 11:38
@Author : stephen
@Email : dz@asj6.wecom.work
@Software: PyCharm
"""
import datetime
import hashlib
import hmac
import urllib.parse
import pytz
import requests
def get_s3_v4_signature(access_key: str, secret_key: str, session_token: str, service: str, region: str,
http_method: str, endpoint_url: str, path: str,
local_file_path: str) -> dict:
timestamp = datetime.datetime.now(tz=pytz.utc).strftime('%Y%m%dT%H%M%SZ')
datestamp = datetime.datetime.now(tz=pytz.utc).strftime('%Y%m%d')
with open(local_file_path, 'rb') as fi:
payload_hash = hashlib.sha256(fi.read()).hexdigest()
canonical_uri = urllib.parse.quote(path)
canonical_querystring = ''
canonical_headers = '\n'.join([f'host:{endpoint_url}',
f'x-amz-content-sha256:{payload_hash}',
f'x-amz-date:{timestamp}']) + '\n'
signed_headers = 'host;x-amz-content-sha256;x-amz-date'
if session_token:
canonical_headers += 'x-amz-security-token:' + session_token + '\n'
signed_headers += ';x-amz-security-token'
canonical_request = '\n'.join([http_method,
canonical_uri,
canonical_querystring,
canonical_headers,
signed_headers,
payload_hash])
credential_scope = datestamp + '/' + region + '/' + service + '/' + 'aws4_request'
string_to_sign = 'AWS4-HMAC-SHA256' + '\n' + timestamp + '\n' + credential_scope + '\n' + hashlib.sha256(
canonical_request.encode('utf-8')).hexdigest()
k_date = hmac.new(('AWS4' + secret_key).encode('utf-8'), datestamp.encode('utf-8'), hashlib.sha256).digest()
k_region = hmac.new(k_date, region.encode('utf-8'), hashlib.sha256).digest()
k_service = hmac.new(k_region, service.encode('utf-8'), hashlib.sha256).digest()
k_signing = hmac.new(k_service, 'aws4_request'.encode('utf-8'), hashlib.sha256).digest()
signature = hmac.new(k_signing, string_to_sign.encode('utf-8'), hashlib.sha256).hexdigest()
auth_header = 'AWS4-HMAC-SHA256' + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' + \
'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature
headers = {
'host': endpoint_url,
'x-amz-content-sha256': payload_hash,
'x-amz-date': timestamp,
'Authorization': auth_header
}
if session_token:
headers['x-amz-security-token'] = session_token
return headers
if __name__ == '__main__':
region_name = 'us-east-1'
temp_access_key = 'ASIA2E'
temp_secret_key = 'hs/M0OgjK++wmz'
temp_session_token = "FwoGZXIvYXdzEAYaDKqiNw1jZICGs4eBRCL1AZOtnLPqc9PYruSgrRFVHS6/EK9XspDKZ3g2TJ"
local_path = 'E:/stephen/testGlacier.txt'
object_key = 'vod1/test2.txt'
timeout_seconds = 3600
bucket_name = 'bucket_name'
s3_endpoint = 's3.{}.amazonaws.com'.format(region_name)
s3_url = 'https://' + s3_endpoint
content_type = 'text/plain'
s3_headers = get_s3_v4_signature(temp_access_key, temp_secret_key, temp_session_token,
's3', region_name, 'PUT', s3_endpoint, '/' + bucket_name + '/' + object_key,
local_path)
s3_headers['Content-Type'] = content_type
url = s3_url + '/' + bucket_name + '/' + object_key
with open(local_path, 'rb') as f:
response = requests.put(url, headers=s3_headers, data=f, timeout=timeout_seconds)
print(response.status_code)
print(response.text)