阿里云(部分)
腾讯云(部分)
百度云(部分)
华为云(部分)
天翼云(部分)
京东云(部分)
Cloudflare R2
A、B操作
V4 签名计算过程
https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/API/sig-v4-header-based-auth.html
import base64
import datetime,hashlib,hmac
import json
from hashlib import sha256
import requests
class SignUtil:
def __header(self,account_id,bucket_name,key_name,domain):
host = "https://{}.r2.cloudflarestorage.com".format(account_id)
CanonicalUri = '/{}/{}'.format(bucket_name, key_name)
if domain != None:
host = domain
CanonicalUri = '/{}'.format(key_name)
t = datetime.datetime.utcnow()
amzdate = t.strftime('%Y%m%dT%H%M%SZ')
datestamp = t.strftime('%Y%m%d')
return host,CanonicalUri,amzdate,datestamp
def __sign(self,key, data):
return hmac.new(key, data.encode(), digestmod=sha256).digest()
def __getSignature(self,datestamp,amzdate,region,canonical_request,access_key_secret):
algorithm = 'AWS4-HMAC-SHA256'
credential_scope = datestamp + '/' + region + '/' + 's3' + '/' + 'aws4_request'
string_to_sign = algorithm + '\n' + amzdate + '\n' + credential_scope + '\n' + hashlib.sha256(
canonical_request.encode('utf-8')).hexdigest()
print('加密字符串:\n' + string_to_sign)
kDate = self.__sign(("AWS4" + access_key_secret).encode(), datestamp)
kRegion = self.__sign(kDate, region)
kService = self.__sign(kRegion, 's3')
kSigning = self.__sign(kService, "aws4_request")
signature = self.__sign(kSigning, string_to_sign)
return signature.hex()
def getSign(self,account_id,access_key_id,access_key_secret,region,bucket_name,key_name,expires=3600,isurl=True,domain=None):
host, CanonicalUri, amzdate, datestamp=self.__header(account_id,bucket_name,key_name,domain)
HTTPMethod = 'GET'
if isurl:
CanonicalQueryString = 'X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential='+access_key_id+'%2F' + datestamp + '%2F'+region+'%2Fs3%2Faws4_request&X-Amz-Date=' + amzdate + '&X-Amz-Expires='+str(expires)+'&X-Amz-SignedHeaders=host'
CanonicalHeaders = 'host:'+ host.replace("https://","") + '\n'
SignedHeaders = 'host'
canonical_request = HTTPMethod + '\n' + CanonicalUri + '\n' + CanonicalQueryString + '\n' + CanonicalHeaders + '\n' + SignedHeaders + '\n' + 'UNSIGNED-PAYLOAD'
print("准备加密请求:" + canonical_request)
headersSign = hashlib.sha256((canonical_request).encode('utf-8')).hexdigest()
print("请求签名:" + headersSign)
signature=self.__getSignature(datestamp,amzdate,region,canonical_request,access_key_secret)
signtext = 'X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=' + access_key_id + '/' + datestamp + '/'+region+'/s3/aws4_request' + '&X-Amz-Date=' + amzdate + '&X-Amz-Expires='+str(expires)+'&X-Amz-SignedHeaders=' + SignedHeaders + '&X-Amz-Signature=' + signature
return host+CanonicalUri+'?'+signtext
else:
CanonicalQueryString = ''
CanonicalHeaders = 'host:'+host.replace("https://","") + '\n' + 'x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n' + 'x-amz-date:' + amzdate + '\n'
SignedHeaders = 'host;x-amz-content-sha256;x-amz-date'
canonical_request = HTTPMethod + '\n' + CanonicalUri + '\n' + CanonicalQueryString + '\n' + CanonicalHeaders + '\n' + SignedHeaders + '\n' + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
print("准备加密请求:" + canonical_request)
headersSign = hashlib.sha256((canonical_request).encode('utf-8')).hexdigest()
print("请求签名:" + headersSign)
signature = self.__getSignature(datestamp, amzdate, region, canonical_request, access_key_secret)
auth = 'AWS4-HMAC-SHA256 Credential=' + access_key_id + '/' + datestamp + '/'+region+'/s3/aws4_request' + ',SignedHeaders=host;x-amz-content-sha256;x-amz-date' + ', Signature=' + signature
headers = {
"Authorization": auth,
"host": host.replace("https://",""),
"x-amz-content-sha256": 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
"x-amz-date": amzdate
}
return headers
policy签名计算
https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html