无法在Python中为方法构造AWS S3签名

无法在Python中为方法构造AWS S3签名,python,amazon-web-services,amazon-s3,Python,Amazon Web Services,Amazon S3,我有一段Python代码,试图创建对AWS的签名HTTPS调用。(来自) 然而,我得到的回应是 403我们计算的请求签名与您提供的签名不匹配。检查服务器上的“密钥和签名方法”。 我可以从AWS CLI运行该命令,这样我就知道我的密钥是有效的,并且我在网上找不到任何与我当前拥有的密钥不同的内容。此外,我已经查看了Boto3,它无法执行我想要的操作 import sys, os, base64, datetime, hashlib, hmac import requests # pip insta

我有一段Python代码,试图创建对AWS的签名HTTPS调用。(来自)

然而,我得到的回应是

403我们计算的请求签名与您提供的签名不匹配。检查服务器上的“密钥和签名方法”。

我可以从AWS CLI运行该命令,这样我就知道我的密钥是有效的,并且我在网上找不到任何与我当前拥有的密钥不同的内容。此外,我已经查看了Boto3,它无法执行我想要的操作

import sys, os, base64, datetime, hashlib, hmac 
import requests # pip install requests

# Standard Variables
aws_service = 's3'
aws_region = 'us-east-1'
endpoint = 'https://s3.amazonaws.com'
algorithm = 'AWS4-HMAC-SHA256'

signedHeaders = 'host;x-amz-content-sha256;x-amz-date'

def test():
  method = 'GET'
  requestParameters = 'max-keys=2'
  path = '/'
  bucket = 'my-test-bucket'
  signatureRequest(method, requestParameters, path, bucket)

# Creates the Authorization Header for the request
def signatureRequest(method, requestParameters, objPath, bucket):
  accessKey = os.environ.get('AWS_ACCESSKEY_ID')
  secretKey = os.environ.get('AWS_SECRET_ACCESSKEY')
  if accessKey is None or secretKey is None:
    print 'No access key is available.'
    sys.exit()

  # Variables
  host= aws_service + '.' + aws_region + '.amazonaws.com'
  t = datetime.datetime.utcnow()
  amzDate = t.strftime('%Y%m%dT%H%M%SZ')
  dateStamp = t.strftime('%Y%m%d')
  canonicalUri = objPath
  canonicalQuerystring = 'Action=' + requestParameters
  payloadHash = hashlib.sha256('').hexdigest() # hash is always '' for GET

  #--- Create the request (Task 1) ---
  canonicalHeaders = 'host:' + host + '\n' + 'x-amz-content-sha256:' + payloadHash + '\n' + 'x-amz-date:' + amzDate + '\n'
  canonicalRequest = method + '\n' + canonicalUri + '\n' + canonicalQuerystring + '\n' + canonicalHeaders + '\n' + signedHeaders + '\n' + payloadHash
  print '--- Canonical Request (Task 1) ---'
  print 'method \ncanonicalUri \ncanonicalQuerystring \ncanonical_headers \nsigned_headers \npayload_hash \n'
  print '%s \n\n' % canonicalRequest

  #--- String to Sign (Task 2) ---
  credentialScope = dateStamp + '/' + aws_region + '/' + aws_service + '/' + 'aws4_request'
  stringToSign = algorithm + '\n' +  amzDate + '\n' +  credentialScope + '\n' +  hashlib.sha256(canonicalRequest).hexdigest()

  #--- Signature (Task 3) ---
  signingKey = getSignatureKey(secretKey, dateStamp, aws_region, aws_service)
  signature = hmac.new(signingKey, (stringToSign).encode('utf-8'), hashlib.sha256).hexdigest()

  #--- authorizationHeader (Task 4) ---
  authorizationHeader = algorithm + ' ' + 'Credential=' + accessKey + '/' + credentialScope + ', ' +  'SignedHeaders=' + signedHeaders + ', ' + 'Signature=' + signature
  requestUrl = endpoint + '?' + canonicalQuerystring # Creates the URL

  #The 'host' header is added automatically by the Python 'requests' library.
  headers = {'x-amz-content-sha256': payloadHash, 'x-amz-date':amzDate, 'Authorization':authorizationHeader}

  sendRequest(requestUrl, headers)

# Key Signing Functions
def sign(key, msg):
  '''
  Copied from https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html
  '''
  return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()

def getSignatureKey(key, dateStamp, regionName, serviceName):
  '''
  Copied from https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html
  '''
  kDate = sign(('AWS4' + key).encode('utf-8'), dateStamp)
  kRegion = sign(kDate, regionName)
  kService = sign(kRegion, serviceName)    
  kSigning = sign(kService, 'aws4_request')
  print '%s' % kSigning
  return kSigning

# Sends the request to AWS and prints the return code
def sendRequest(url, headers):
  r = requests.get(url, headers=headers)
  print 'Response from AWS: %d\n' % r.status_code
  print r.text

我很想知道boto3不能满足您的需求的地方有哪些。boto3涵盖了AWS中的所有API。此外,它还为您处理签名。如果您要自己构建签名,您将进入一个痛苦和痛苦的巨大世界。您肯定应该深入研究boto3。
canonicalQuerystring='Action='+requestParameters
不正确ct.字符串
Action=
不属于这里。S3 API是REST,而不是查询。
requestParameters
也需要按词汇排序,尽管在这种情况下,您似乎只有一个。据我所知,boto3不能满足@spg的要求,我的最终目标是能够生成此类命令的签名URL请求s GET Bucket(List Objects)v2。如果有办法的话,我愿意使用boto3,但是,我很喜欢使用它作为HTTPS响应的练习。谢谢!我确信有一个类可以在boto3(或botocore)中重用这将为您处理签名。只是好奇,为什么您需要为GET Bucket生成签名URL?也许还有其他选择。我想知道boto3不能满足您的需要的是什么。boto3涵盖AWS中的所有API。此外,它还为您处理签名。如果您要自己构建签名,您将进入一个巨大的应用程序世界痛苦和痛苦。你肯定应该更深入地研究这两者。
canonicalQuerystring='Action='+requestParameters
不正确。字符串
Action=
不属于这里。S3API是REST,而不是Query。
requestParameters
也需要按词汇排序,尽管在这种情况下,你似乎只有一个。Fro据我所知,boto3无法满足@spg的要求,我的最终目标是能够生成GET Bucket(列表对象)等命令的签名URL请求v2.如果有办法的话,我愿意使用boto3,不过,我很喜欢用它作为HTTPS响应的练习。谢谢!我确信有一个类可以在boto3(或botocore)中重用,可以为您处理签名。只是好奇,为什么您需要为GET Bucket生成签名URL?也许还有其他选择。