当前位置:   article > 正文

python实现阿里云Signature签名计算_specified parameter version is not valid

specified parameter version is not valid

遇到的问题

以前工作中写脚本访问阿里云的资源时,都是通过调用系统命令(调用CLI工具)的方式,这次尝试通过http请求来实现想要的操作。
本次实现中遇到的问题:
1、向api发送请求是总是返回报错:Specified parameter Version is not valid,从报错上看是参数中设置的Version的值有问题,但反复核实请求中带的Version并没有问题。
解决方法:如果你遇到同样的问题,估计跟我一样,构建好请求url后,在向api发送请求时也是以调用系统命令(curl)的方式来实现的,这里要把请求的url用引号引起来,形式如下:cmd = "curl ‘http://xxx.example.com?Aciton=XXXX&…’ ",具体为什,据说是因为url中的&符号,是一个命令行执行后台挂起的标志,导致curl命令执行与预期不符,我并没有去验证,大体上应该就是这么回事了
2、在解决了上一个问题后,再次发送请求,返回结果为:errorCode:IncompleteSignature,msg:“The request signature does not conform to Aliyun standards.”
解决方法:报错很明显是计算得到的签名Signature有问题,问题出在待签名字符串上,待签名字符串中的参数部分,我只对它进行了一次urlencode操作,还需要再进行一次percentEncode操作,将其中的等号“=”,编码成%3D

签名代码实现

下面记录一下代码的实现,学过的东西还是要多复习,毕竟编码经验还不纯熟。(我安装的是python3.7的版本)
用法:aliyunTool.py -f params.json
params.json示例:

{
        "endpoint": "https://ecs.aliyuncs.com",
        "AccessKeyId": "xxxxxxxxxxxxxxxxxxxxxxx",
        "AccessKeySecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "Params": {
            "AccessKeyId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "Format": "json",
            "Version": "2014-05-26",
            "SignatureMethod": "HMAC-SHA1",
            "Timestamp": "",
            "SignatureVersion": "1.0",
            "SignatureNonce": "",
            "Action": "DescribeInstances",
            "RegionId": "cn-beijing",
            "PageSize": "50"
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

代码示例,复制可直接使用:

import datetime
import urllib.request
import urllib.parse
import hmac
import base64
import json
import uuid
import argparse
import copy
def getConfigFromFile(configFile):
    config_file = open(configFile)
    config = json.load(config_file)
    config_file.close()
    # 计算时间戳参数,使用的是utc时间,并格式化成指定的格式
    return config

def  requestByConfig(config):
    #计算时间戳参数,使用的是utc时间,并格式化成指定的格式
    timestamp = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
    #下面三个参数要求全局唯一,使用uuid生成随机字符串
    #ClientToken = str(uuid.uuid4()) #本示例中用不到
    #Token = str(uuid.uuid4()) #本示例中用不到
    signatureNonce = str(uuid.uuid4())

    #下面根据阿里云文档计算待签名字符串
    #def generateToSignStr(commonparams,customparams):
    #首先合并公共参数和自定义参数,然后排序
    params = copy.copy(config["Params"])
    params["Timestamp"] = timestamp
    params["SignatureNonce"] = signatureNonce
    sortedParams = sorted(params.items(), key=lambda x: x[0])
    #然后对合并排序后的参数进行urlencode编码,得到的是多个key=value的键值对通过&符号连接后组成的字符串
    urlencodeParams = urllib.parse.urlencode(sortedParams).replace("+","%20").replace("*","%2A").replace("%7E","~")
    #再处理一次,将urlencode后的字符串中的“=”和“&”进行percent编码
    urlencodeParams = urllib.parse.quote_plus(urlencodeParams)
    #最后生成待签名字符串
    toSignStr = "GET"+"&"+urllib.parse.quote_plus("/")+"&"+urlencodeParams
    #计算签名
    h = hmac.new((config["AccessKeySecret"]+"&").encode(),toSignStr.encode(),"sha1")
    signature = base64.encodebytes(h.digest()).strip().decode()

    #将Signature添加到请求参数,生成请求url
    params["Signature"] = signature
    url = config["endpoint"]+"?"+urllib.parse.urlencode(params).replace("+","%20")
    print(url)
#发送请求并打印结果
    res=None
    try:
        response = urllib.request.urlopen(url)
        # 先将结果转换成字典,再转换成json对象,格式化输出
        res = json.load(response)
#        print(json.dumps(res, sort_keys=True, indent=2))
        return res
    except IOError as e:
        print(e.read())
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-f", "--conf", type=str, default="config.json", help="请求接口的配置及参数的配置文件")
    args = parser.parse_args()
    conf = getConfigFromFile(args.conf)
    x = requestByConfig(conf)
    print(x)

    params = {
        "endpoint": "https://ecs.aliyuncs.com",
        "AccessKeyId": "xxxxxxxxxxxxxxxxxxxxxxx",
        "AccessKeySecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "Params": {
            "AccessKeyId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "Format": "json",
            "Version": "2014-05-26",
            "SignatureMethod": "HMAC-SHA1",
            "Timestamp": "",
            "SignatureVersion": "1.0",
            "SignatureNonce": "",
            "Action": "DescribeInstances",
            "RegionId": "cn-beijing",
            "PageSize": "50"
        }
    }
    
    y = requestByConfig(params)
    print(y)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/732616
推荐阅读
相关标签
  

闽ICP备14008679号