赞
踩
# -*- encoding: utf-8 -*- """ @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') # 计算文件内容的 SHA-256 哈希值作为 payload hash with open(local_file_path, 'rb') as fi: payload_hash = hashlib.sha256(fi.read()).hexdigest() # 对 URL 进行转义以生成规范的 URI 和查询字符串 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 # 构建 HTTP 请求头部,并包含授权头部。如果提供了会话令牌,则也应将其包含在请求头中 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__': # 输入您获得的临时访问令牌,包括访问密钥 ID、密钥和会话令牌。 region_name = 'us-east-1' temp_access_key = 'ASIA2E' temp_secret_key = 'hs/M0OgjK++wmz' temp_session_token = "FwoGZXIvYXdzEAYaDKqiNw1jZICGs4eBRCL1AZOtnLPqc9PYruSgrRFVHS6/EK9XspDKZ3g2TJ" # 指定要上传的本地文件路径和 S3 存储桶中的对象 key 值,并设置请求超时时间,单位为秒。 local_path = 'E:/stephen/testGlacier.txt' object_key = 'vod1/test2.txt' timeout_seconds = 3600 bucket_name = 'bucket_name' # 初始化 S3 存储客户端 s3_endpoint = 's3.{}.amazonaws.com'.format(region_name) s3_url = 'https://' + s3_endpoint content_type = 'text/plain' # 构建 HTTP 头部,包含授权信息和必要的元数据 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,并将本地文件上传到指定的存储桶中 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)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。