• 关于 python x++ 的搜索结果

回答

应用一些正则表达式并转换为rdd可能对您有用。 先使用textFile以下方法读取文件: a=spark.read.option('multiline',"true").text('aa.json')a.show(truncate=False) +-------------------------------------+ |value | +-------------------------------------+ |[[{"foo":"test1"},{"foo1":"test21"}],| |[{"foo":"test2"},{"foo1":"test22"}], | |[{"foo":"test3"},{"foo1":"test23"}]] | +-------------------------------------+ 现在我们可以使用pyspark.sql.functions.regexp_replace从每行中删除额外的方括号和尾随逗号: from pyspark.sql.functions import regexp_replacea = a.select(regexp_replace("value", "(^[(?=[))|((?<=])]$)|(,$)", "").alias("value"))a.show(truncate=False) +-----------------------------------+ |value | +-----------------------------------+ |[{"foo":"test1"},{"foo1":"test21"}]| |[{"foo":"test2"},{"foo1":"test22"}]| |[{"foo":"test3"},{"foo1":"test23"}]| +-----------------------------------+ 这里的模式是逻辑或以下模式: ^[(?=[):字符串开头后跟[[(第二[个是非捕获组)(?<=])]$:]]在字符串的末尾(第]一个是非捕获组),$:字符串末尾的逗号任何匹配的模式都将替换为空字符串。 现在转换为rdd并使用json.loads将行解析为字典列表。然后将所有这些字典合并到一个字典中并调用pyspark.sql.Row构造函数。最后调用.toDF转换回DataFrame。 From How to merge two dictionaries in a single expression? This code works for python 2 and 3 def merge_two_dicts(x, y): z = x.copy() # start with x's keys and values z.update(y) # modifies z with y's keys and values & returns None return z import jsonfrom pyspark.sql import Rowfrom functools import reduce a.rdd.map(lambda x: Row(**reduce(merge_two_dicts, json.loads(x['value'])))).toDF().show() +-----+------+ | foo| foo1| +-----+------+ |test1|test21| |test2|test22| |test3|test23| +-----+------+

社区小助手 2019-12-02 01:50:55 0 浏览量 回答数 0

回答

1、lambda是什么?举个例子如下:func=lambda x:x+1print(func(1))2print(func(2))3以上lambda等同于以下函数def func(x):return(x+1)复制代码  可以这样认为,lambda作为一个表达式,定义了一个匿名函数,上例的代码x为入口参数,x+1为函数体。在这里lambda简化了函数定义的书写形式。是代码更为简洁,但是使用函数的定义方式更为直观,易理解。  Python中,也有几个定义好的全局函数方便使用的,filter, map, reduce。from functools import reduce foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]print (list(filter(lambda x: x % 3 == 0, foo)))[18, 9, 24, 12, 27]print (list(map(lambda x: x * 2 + 10, foo)))[14, 46, 28, 54, 44, 58, 26, 34, 64]print (reduce(lambda x, y: x + y, foo))139复制代码  上面例子中的map的作用,非常简单清晰。但是,Python是否非要使用lambda才能做到这样的简洁程度呢?在对象遍历处理方面,其实Python的for..in..if语法已经很强大,并且在易读上胜过了lambda。     比如上面map的例子,可以写成:print ([x * 2 + 10 for x in foo]) 非常的简洁,易懂。         filter的例子可以写成:print ([x for x in foo if x % 3 == 0]) 同样也是比lambda的方式更容易理解。

元芳啊 2019-12-02 01:04:40 0 浏览量 回答数 0

问题

在PHP或NodeJS中实现Python编码代码

一码平川MACHEL 2019-12-01 19:31:19 660 浏览量 回答数 1

新用户福利专场,云服务器ECS低至96.9元/年

新用户福利专场,云服务器ECS低至96.9元/年

回答

Linux默认是已经安装好了Python程序 目前来说,大多数的Linux发行版是安装了两个版本的Python程序 一个是Python 2.x 一个是Python 3.x 一些系统自带的程序文件需要Python 2的支持,另外Python 3又是大势所趋 所以,我们最好不要动系统的Python版本 需要使用哪个版本直接声明就可以了 工具/原料Python程序方法/步骤我们在Linux系统上打开终端输入python会弹出Python 2的版本和解释器输入python3会弹出Python 3的版本和解释器所以我们一般情况下,运行python 2的程序就输入命令python 程序文件运行python 3的程序输入命令python3 程序文件如何在Linux上使用Python这里我们默认使用版本为Python 3在终端输入命令Python3弹出Python的解释器以>>>开头我们可以在上面输入Python程序它会直接输出结果比如:我们这里输入32+46,输出结果为78输入print('hello python'),输出结果hello python注意:当我们运行.py文件时,文件里的32+46是不会直接打印出来的必须加打印命令print(32+46)如何在Linux上使用Python我们退出python3解释器的快捷键不是Ctrl+C而是Ctrl+Z如何在Linux上使用Python新建文本文件保存名为:hello.py内容: !/usr/bin/python3 print("Hello, World!");第一行是指定解释的位置使用哪一个python版本第二行使我们的Python程序如何在Linux上使用Python执行了这个程序之前我们需要给予他可执行权限没有可执行权限其实也是可以执行的但是必须得是完整路径如何在Linux上使用Python直接在终端./hello.py 就可以运行出正确的结果也可以加上python3命令python3 /home/linuxmint/下载/hello.py注意:第一个命令在没有加可执行权限之前是不可以直接运行的如何在Linux上使用Python最后推荐两个学Python3的网站第一个是廖雪峰的官方网站,里面的Python教程也写得比较好第二个是RUNOOB,里面有很多的学习资源如何在Linux上使用Python如何在Linux上使用Python

xuning715 2019-12-02 01:10:36 0 浏览量 回答数 0

回答

问题是,一旦您持久保存数据,second_id就会将其合并到缓存表中,不再被视为常量。因此,计划程序无法再推断查询应该表示为笛卡尔积,并使用标准SortMergeJoin的哈希分区second_id。在不使用持久性的情况下实现相同的结果将是微不足道的 udffrom pyspark.sql.functions import lit, pandas_udf, PandasUDFType@pandas_udf('integer', PandasUDFType.SCALAR) def identity(x):return x second_df = second_df.withColumn('second_id', identity(lit(1)))result_df = first_df.join(second_df, first_df.first_id == second_df.second_id, 'inner') result_df.explain()== Physical Plan ==*(6) SortMergeJoin [cast(first_id#4 as int)], [second_id#129], Inner:- *(2) Sort [cast(first_id#4 as int) ASC NULLS FIRST], false, 0: +- Exchange hashpartitioning(cast(first_id#4 as int), 200): +- *(1) Filter isnotnull(first_id#4): +- Scan ExistingRDD[first_id#4]+- *(5) Sort [second_id#129 ASC NULLS FIRST], false, 0 +- Exchange hashpartitioning(second_id#129, 200) +- *(4) Project [some_value#6, pythonUDF0#154 AS second_id#129] +- ArrowEvalPython [identity(1)], [some_value#6, pythonUDF0#154] +- *(3) Project [some_value#6] +- *(3) Filter isnotnull(pythonUDF0#153) +- ArrowEvalPython [identity(1)], [some_value#6, pythonUDF0#153] +- Scan ExistingRDD[some_value#6]然而,SortMergeJoin这不是你应该尝试在这里实现的。使用常量键,除了玩具数据外,它会导致极端的数据偏差,并且可能会失败。然而,笛卡尔积虽然价格昂贵,但不会遇到这个问题,因此这里应该优先考虑。因此,它建议启用交叉连接或使用显式交叉连接语法(Spark 2.x的spark.sql.crossJoin.enabled)并继续。一个悬而未决的问题仍然是如何在缓存数据时防止意外行为。不幸的是,我没有为此做好准备。我相当确定可以使用自定义优化器规则,但这不是单独用Python完成的事情。

社区小助手 2019-12-02 01:47:43 0 浏览量 回答数 0

问题

Java中这个Python列表的等价性是什么样的?

一码平川MACHEL 2019-12-01 19:31:49 571 浏览量 回答数 3

问题

阿里云oss 上传回调自定义参数 json

晨曦的希望 2019-12-01 19:41:08 554 浏览量 回答数 0

回答

eval函数将字符串当成有效Python表达式来求值,并返回计算结果x = 1eval('x+1')eval('x==1')与之对应的repr函数,它能够将Python的变量和表达式转换为字符串表示repr(x==1)repr(x+1)希望我提供的答案能够帮助到你,答案满意还请采纳一下,谢谢。另外,你可以继续留言或者到论坛参与更多的互动。

大财主 2019-12-02 01:05:06 0 浏览量 回答数 0

问题

创建一个Spark udf函数来迭代一个字节数组并将其转换为数字

社区小助手 2019-12-01 19:23:41 708 浏览量 回答数 1

回答

Python 变量类型变量存储在内存中的值。这就意味着在创建变量时会在内存中开辟一个空间。基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中。因此,变量可以指定不同的数据类型,这些变量可以存储整数,小数或字符。 变量赋值Python 中的变量赋值不需要类型声明。每个变量在内存中创建,都包括变量的标识,名称和数据这些信息。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。等号(=)用来给变量赋值。等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的值。例如:实例(Python 2.0+) !/usr/bin/python -- coding: UTF-8 -- counter = 100 # 赋值整型变量miles = 1000.0 # 浮点型name = "John" # 字符串 print counterprint milesprint name 运行实例 »以上实例中,100,1000.0和"John"分别赋值给counter,miles,name变量。执行以上程序会输出如下结果:1001000.0John多个变量赋值Python允许你同时为多个变量赋值。例如:a = b = c = 1以上实例,创建一个整型对象,值为1,三个变量被分配到相同的内存空间上。您也可以为多个对象指定多个变量。例如:a, b, c = 1, 2, "john"以上实例,两个整型对象1和2的分配给变量 a 和 b,字符串对象 "john" 分配给变量 c。 标准数据类型在内存中存储的数据可以有多种类型。例如,一个人的年龄可以用数字来存储,他的名字可以用字符来存储。Python 定义了一些标准类型,用于存储各种类型的数据。Python有五个标准的数据类型:Numbers(数字)String(字符串)List(列表)Tuple(元组)Dictionary(字典) Python数字数字数据类型用于存储数值。他们是不可改变的数据类型,这意味着改变数字数据类型会分配一个新的对象。当你指定一个值时,Number对象就会被创建:var1 = 1var2 = 10您也可以使用del语句删除一些对象的引用。del语句的语法是:del var1[,var2[,var3[....,varN]]]]您可以通过使用del语句删除单个或多个对象的引用。例如:del vardel var_a, var_bPython支持四种不同的数字类型:int(有符号整型)long(长整型[也可以代表八进制和十六进制])float(浮点型)complex(复数)实例一些数值类型的实例:int long float complex10 51924361L 0.0 3.14j100 -0x19323L 15.20 45.j-786 0122L -21.9 9.322e-36j080 0xDEFABCECBDAECBFBAEl 32.3e+18 .876j-0490 535633629843L -90. -.6545+0J-0x260 -052318172735L -32.54e100 3e+26J0x69 -4721885298529L 70.2E-12 4.53e-7j长整型也可以使用小写 l,但是还是建议您使用大写 L,避免与数字 1 混淆。Python使用 L 来显示长整型。Python 还支持复数,复数由实数部分和虚数部分构成,可以用 a + bj,或者 complex(a,b) 表示, 复数的实部 a 和虚部 b 都是浮点型。 Python字符串字符串或串(String)是由数字、字母、下划线组成的一串字符。一般记为 :s="a1a2···an"(n>=0)它是编程语言中表示文本的数据类型。python的字串列表有2种取值顺序:从左到右索引默认0开始的,最大范围是字符串长度少1从右到左索引默认-1开始的,最大范围是字符串开头如果你要实现从字符串中获取一段子字符串的话,可以使用变量 [头下标:尾下标],就可以截取相应的字符串,其中下标是从 0 开始算起,可以是正数或负数,下标可以为空表示取到头或尾。比如:s = 'ilovepython's[1:5]的结果是love。当使用以冒号分隔的字符串,python返回一个新的对象,结果包含了以这对偏移标识的连续的内容,左边的开始是包含了下边界。上面的结果包含了s[1]的值l,而取到的最大范围不包括上边界,就是s[5]的值p。加号(+)是字符串连接运算符,星号(*)是重复操作。如下实例:实例(Python 2.0+) !/usr/bin/python -- coding: UTF-8 -- str = 'Hello World!' print str # 输出完整字符串print str[0] # 输出字符串中的第一个字符print str[2:5] # 输出字符串中第三个至第五个之间的字符串print str[2:] # 输出从第三个字符开始的字符串print str * 2 # 输出字符串两次print str + "TEST" # 输出连接的字符串以上实例输出结果:Hello World!Hllollo World!Hello World!Hello World!Hello World!TESTPython列表List(列表) 是 Python 中使用最频繁的数据类型。列表可以完成大多数集合类的数据结构实现。它支持字符,数字,字符串甚至可以包含列表(即嵌套)。列表用 [ ] 标识,是 python 最通用的复合数据类型。列表中值的切割也可以用到变量 [头下标:尾下标] ,就可以截取相应的列表,从左到右索引默认 0 开始,从右到左索引默认 -1 开始,下标可以为空表示取到头或尾。加号 + 是列表连接运算符,星号 * 是重复操作。如下实例:实例(Python 2.0+) !/usr/bin/python -- coding: UTF-8 -- list = [ 'runoob', 786 , 2.23, 'john', 70.2 ]tinylist = [123, 'john'] print list # 输出完整列表print list[0] # 输出列表的第一个元素print list[1:3] # 输出第二个至第三个元素 print list[2:] # 输出从第三个开始至列表末尾的所有元素print tinylist * 2 # 输出列表两次print list + tinylist # 打印组合的列表以上实例输出结果:['runoob', 786, 2.23, 'john', 70.2]runoob[786, 2.23][2.23, 'john', 70.2][123, 'john', 123, 'john']['runoob', 786, 2.23, 'john', 70.2, 123, 'john']Python元组元组是另一个数据类型,类似于List(列表)。元组用"()"标识。内部元素用逗号隔开。但是元组不能二次赋值,相当于只读列表。实例(Python 2.0+) !/usr/bin/python -- coding: UTF-8 -- tuple = ( 'runoob', 786 , 2.23, 'john', 70.2 )tinytuple = (123, 'john') print tuple # 输出完整元组print tuple[0] # 输出元组的第一个元素print tuple[1:3] # 输出第二个至第三个的元素 print tuple[2:] # 输出从第三个开始至列表末尾的所有元素print tinytuple * 2 # 输出元组两次print tuple + tinytuple # 打印组合的元组以上实例输出结果:('runoob', 786, 2.23, 'john', 70.2)runoob(786, 2.23)(2.23, 'john', 70.2)(123, 'john', 123, 'john')('runoob', 786, 2.23, 'john', 70.2, 123, 'john')以下是元组无效的,因为元组是不允许更新的。而列表是允许更新的:实例(Python 2.0+) !/usr/bin/python -- coding: UTF-8 -- tuple = ( 'runoob', 786 , 2.23, 'john', 70.2 )list = [ 'runoob', 786 , 2.23, 'john', 70.2 ]tuple[2] = 1000 # 元组中是非法应用list[2] = 1000 # 列表中是合法应用 Python 字典字典(dictionary)是除列表以外python之中最灵活的内置数据结构类型。列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。字典用"{ }"标识。字典由索引(key)和它对应的值value组成。实例(Python 2.0+) !/usr/bin/python -- coding: UTF-8 -- dict = {}dict['one'] = "This is one"dict[2] = "This is two" tinydict = {'name': 'john','code':6734, 'dept': 'sales'} print dict['one'] # 输出键为'one' 的值print dict[2] # 输出键为 2 的值print tinydict # 输出完整的字典print tinydict.keys() # 输出所有键print tinydict.values() # 输出所有值输出结果为:This is oneThis is two{'dept': 'sales', 'code': 6734, 'name': 'john'}['dept', 'code', 'name']['sales', 6734, 'john']Python数据类型转换有时候,我们需要对数据内置的类型进行转换,数据类型的转换,你只需要将数据类型作为函数名即可。以下几个内置的函数可以执行数据类型之间的转换。这些函数返回一个新的对象,表示转换的值。函数 描述int(x [,base])将x转换为一个整数long(x [,base] )将x转换为一个长整数float(x)将x转换到一个浮点数complex(real [,imag])创建一个复数str(x)将对象 x 转换为字符串repr(x)将对象 x 转换为表达式字符串eval(str)用来计算在字符串中的有效Python表达式,并返回一个对象tuple(s)将序列 s 转换为一个元组list(s)将序列 s 转换为一个列表set(s)转换为可变集合dict(d)创建一个字典。d 必须是一个序列 (key,value)元组。frozenset(s)转换为不可变集合chr(x)将一个整数转换为一个字符unichr(x)将一个整数转换为Unicode字符ord(x)将一个字符转换为它的整数值hex(x)将一个整数转换为一个十六进制字符串oct(x)将一个整数转换为一个八进制字符串

xuning715 2019-12-02 01:10:21 0 浏览量 回答数 0

问题

apache+php+shell+python 环境变量传递问题?报错

爱吃鱼的程序员 2020-06-22 15:15:16 0 浏览量 回答数 1

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:44 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:44 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:45 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:43 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:43 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:44 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:45 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:45 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:44 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:44 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:45 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:44 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:43 0 浏览量 回答数 0

回答

详细解答可以参考官方帮助文档 用户可以在HTTP请求中增加 Authorization 的Header来包含签名(Signature)信息,表明这个消息已被授权。 Authorization字段计算的方法 Authorization = "OSS " + AccessKeyId + ":" + Signature Signature = base64(hmac-sha1(AccessKeySecret, VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedOSSHeaders + CanonicalizedResource)) AccessKeySecret 表示签名所需的密钥 VERB表示HTTP 请求的Method,主要有PUT,GET,POST,HEAD,DELETE等 \n 表示换行符 Content-MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。详情参看RFC2616 Content-MD5。 Content-Type 表示请求内容的类型,如”application/octet-stream”,也可以为空 Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT” CanonicalizedOSSHeaders 表示以 x-oss- 为前缀的http header的字典序排列 CanonicalizedResource 表示用户想要访问的OSS资源 其中,Date和CanonicalizedResource不能为空;如果请求中的Date时间和OSS服务器的时间差15分钟以上,OSS服务器将拒绝该服务,并返回HTTP 403错误。 构建CanonicalizedOSSHeaders的方法 所有以 x-oss- 为前缀的HTTP Header被称为CanonicalizedOSSHeaders。它的构建方法如下: 将所有以 x-oss- 为前缀的HTTP请求头的名字转换成 小写 。如X-OSS-Meta-Name: TaoBao转换成x-oss-meta-name: TaoBao。 如果请求是以STS获得的AccessKeyId和AccessKeySecret发送时,还需要将获得的security-token值,以 x-oss-security-token:security-token 的形式加入到签名字符串中。 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列。 删除请求头和内容之间分隔符两端出现的任何空格。如x-oss-meta-name: TaoBao转换成:x-oss-meta-name:TaoBao。 将每一个头和内容用 \n 分隔符分隔拼成最后的CanonicalizedOSSHeaders。 说明 CanonicalizedOSSHeaders可以为空,无需添加最后的 \n。 如果只有一个,则如 x-oss-meta-a\n,注意最后的\n。 如果有多个,则如 x-oss-meta-a:a\nx-oss-meta-b:b\nx-oss-meta-c:c\n, 注意最后的\n。 构建CanonicalizedResource的方法 用户发送请求中想访问的OSS目标资源被称为CanonicalizedResource。它的构建方法如下: 将CanonicalizedResource置成空字符串 ""; 放入要访问的OSS资源 /BucketName/ObjectName(无ObjectName则CanonicalizedResource为”/BucketName/“,如果同时也没有BucketName则为“/”) 如果请求的资源包括子资源(SubResource) ,那么将所有的子资源按照字典序,从小到大排列并以 & 为分隔符生成子资源字符串。在CanonicalizedResource字符串尾添加 ?和子资源字符串。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&uploadId=UploadId 如果用户请求在指定了查询字符串(QueryString,也叫Http Request Parameters),那么将这些查询字符串及其请求值按照 字典序,从小到大排列,以 & 为分隔符,按参数添加到CanonicalizedResource中。此时的CanonicalizedResource如:/BucketName/ObjectName?acl&response-content-type=ContentType&uploadId=UploadId。 说明 OSS目前支持的子资源(sub-resource)包括:acl,uploads,location,cors,logging,website,referer,lifecycle,delete,append,tagging,objectMeta,uploadId,partNumber,security-token,position,img,style,styleName,replication,replicationProgress,replicationLocation,cname,bucketInfo,comp,qos,live,status,vod,startTime,endTime,symlink,x-oss-process,response-content-type,response-content-language,response-expires,response-cache-control,response-content-disposition,response-content-encoding等 子资源(sub-resource)有三种类型: 资源标识,如子资源中的acl,append,uploadId,symlink等,详见关于Bucket的操作和关于Object的操作。 指定返回Header字段,如 response-***,详见GetObject的Request Parameters。 文件(Object)处理方式,如 x-oss-process,用于文件的处理方式,如图片处理。 计算签名头规则 签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进行 UTF-8 编码,再与 AccessKeySecret计算最终签名。 签名的方法用RFC 2104中定义的HMAC-SHA1方法,其中Key为 AccessKeySecret` 。 Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符 \n 代替。 在所有非HTTP标准定义的header中,只有以 x-oss- 开头的header,需要加入签名字符串;其他非HTTP标准header将被OSS忽略(如上例中的x-oss-magic是需要加入签名字符串的)。 以 x-oss- 开头的header在签名验证前需要符合以下规范: header的名字需要变成小写。 header按字典序自小到大排序。 分割header name和value的冒号前后不能有空格。 每个Header之后都有一个换行符“\n”,如果没有Header,CanonicalizedOSSHeaders就设置为空。 签名示例 假如AccessKeyId是”44CF9590006BF252F707”,AccessKeySecret是”OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV” 请求 签名字符串计算公式 签名字符串 PUT /nelson HTTP/1.0 Content-MD5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource)) “PUT\n eB5eJF1ptWaXm4bijSPyxw==\n text/html\n Thu, 17 Nov 2005 18:49:58 GMT\n x-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nels 可用以下方法计算签名(Signature): python示例代码: import base64 import hmac import sha h = hmac.new("OtxrzxIsfpFjA7SwPzILwy8Bw21TLhquhboDYROV", "PUT\nODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-magic:abracadabra\nx-oss-meta-author:foo@bar.com\n/oss-example/nelson", sha) Signature = base64.b64encode(h.digest()) print("Signature: %s" % Signature) 签名(Signature)计算结果应该为 26NBxoKdsyly4EDv6inkoDft/yA=,因为Authorization = “OSS “ + AccessKeyId + “:” + Signature所以最后Authorization为 “OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA=”然后加上Authorization头来组成最后需要发送的消息: PUT /nelson HTTP/1.0 Authorization:OSS 44CF9590006BF252F707:26NBxoKdsyly4EDv6inkoDft/yA= Content-Md5: eB5eJF1ptWaXm4bijSPyxw== Content-Type: text/html Date: Thu, 17 Nov 2005 18:49:58 GMT Host: oss-example.oss-cn-hangzhou.aliyuncs.com X-OSS-Meta-Author: foo@bar.com X-OSS-Magic: abracadabra 细节分析 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId。 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument。 OSS所有的请求都必须使用HTTP 1.1协议规定的GMT时间格式。其中,日期的格式为:date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)上述日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied。 传入请求的时间必须在OSS服务器当前时间之后的15分钟以内,否则返回403 Forbidden。错误码:RequestTimeTooSkewed。 如果AccessKeyId是active的,但OSS判断用户的请求发生签名错误,则返回403 Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串。用户可以根据OSS的response来检查自己的签名字符串是否正确。返回示例:<?xml version="1.0" ?> <Error> <Code> SignatureDoesNotMatch </Code> <Message> The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message> <StringToSignBytes> 47 45 54 0a 0a 0a 57 65 64 2c 20 31 31 20 4d 61 79 20 32 30 31 31 20 30 37 3a 35 39 3a 32 35 20 47 4d 54 0a 2f 75 73 72 65 61 6c 74 65 73 74 3f 61 63 6c </StringToSignBytes> <RequestId> 1E446260FF9B10C2 </RequestId> <HostId> oss-cn-hangzhou.aliyuncs.com </HostId> <SignatureProvided> y5H7yzPsA/tP4+0tH1HHvPEwUv8= </SignatureProvided> <StringToSign> GET Wed, 11 May 2011 07:59:25 GMT /oss-example?acl </StringToSign> <OSSAccessKeyId> AKIAIVAKMSMOY7VOMRWQ </OSSAccessKeyId> </Error> 说明 OSS SDK已经实现签名,用户使用OSS SDK不需要关注签名问题。如果您想了解具体语言的签名实现,请参考OSS SDK的代码。OSS SDK签名实现的文件如下表: SDK 签名实现 Java SDK OSSRequestSigner.java Python SDK auth.py .Net SDK OssRequestSigner.cs PHP SDK OssClient.php C SDK oss_auth.c JavaScript SDK client.js Go SDK auth.go Ruby SDK util.rb iOS SDK OSSModel.m Android SDK OSSUtils.java 当您自己实现签名,访问OSS报 SignatureDoesNotMatch 错误时,请使用可视化签名工具确认签名并排除错误。 常见问题 Content-MD5的计算方法 Content-MD5的计算 以消息内容为"123456789"来说,计算这个字符串的Content-MD5 正确的计算方式: 标准中定义的算法简单点说就是: 1. 先计算MD5加密的二进制数组(128位)。 2. 再对这个二进制进行base64编码(而不是对32位字符串编码)。 以Python为例子: 正确计算的代码为: >>> import base64,hashlib >>> hash = hashlib.md5() >>> hash.update("0123456789") >>> base64.b64encode(hash.digest()) 'eB5eJF1ptWaXm4bijSPyxw==' 需要注意 正确的是:hash.digest(),计算出进制数组(128位) >>> hash.digest() 'x\x1e^$]i\xb5f\x97\x9b\x86\xe2\x8d#\xf2\xc7' 常见错误是直接对计算出的32位字符串编码进行base64编码。 例如,错误的是:hash.hexdigest(),计算得到可见的32位字符串编码 >>> hash.hexdigest() '781e5e245d69b566979b86e28d23f2c7' 错误的MD5值进行base64编码后的结果: >>> base64.b64encode(hash.hexdigest()) 'NzgxZTVlMjQ1ZDY5YjU2Njk3OWI4NmUyOGQyM2YyYzc='

2019-12-01 23:13:45 0 浏览量 回答数 0

问题

字典无限循环意外退出

一码平川MACHEL 2019-12-01 19:32:13 435 浏览量 回答数 1

问题

使用Boost Python从C ++向python中的类成员变量赋值

祖安文状元 2020-02-23 16:14:19 1 浏览量 回答数 1

回答

在同一个文件夹下 调用函数: A.py文件: [python] view plain copydef add(x,y): print('和为:%d'%(x+y)) B.py文件:[python] view plain copyimport A A.add(1,2) 或[python] view plain copyfrom A import add add(1,2) 调用类: A.py文件: [python] view plain copyclass A: def __init__(self,xx,yy): self.x=xx self.y=yy def add(self): print("x和y的和为:%d"%(self.x+self.y)) B.py文件:[python] view plain copyfrom A import A a=A(2,3) a.add() 或[python] view plain copyimport A a=A.A(2,3) a.add() 在不同文件夹下 A.py文件的文件路径:E:PythonProjectwinycg B.py文件:[python] view plain copyimport sys sys.path.append(r'E:PythonProjectwinycg') '''''python import模块时, 是在sys.path里按顺序查找的。 sys.path是一个列表,里面以字符串的形式存储了许多路径。 使用A.py文件中的函数需要先将他的文件路径放到sys.path中''' import A a=A.A(2,3) a.add()

xuning715 2019-12-02 01:10:15 0 浏览量 回答数 0

回答

复数是由一个实数和一个虚数组合构成,表示为:x+yj一个负数时一对有序浮点数 (x,y),其中 x 是实数部分,y 是虚数部分。Python 语言中有关负数的概念:1、虚数不能单独存在,它们总是和一个值为 0.0 的实数部分一起构成一个复数2、复数由实数部分和虚数部分构成3、表示虚数的语法:real+imagej4、实数部分和虚数部分都是浮点数5、虚数部分必须有后缀j或Jcoding=utf8aa=123-12jprint aa.real # output 实数部分 123.0 print aa.imag # output虚数部分 -12.0输出结果为:123.0-12.0

ylrf1212 2019-12-02 01:07:46 0 浏览量 回答数 0

回答

需要安装gl库,用下面的命令试一下:$ sudo apt-get install git-core gnupg flex bison gperf build-essential \ zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \ libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \ libgl1-mesa-dev g++-multilib mingw32 openjdk-6-jdk tofrodos \ python-markdown libxml2-utils xsltproc zlib1g-dev:i386$ sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so

洵云 2019-12-02 00:29:09 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 云栖号物联网 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站 云栖号弹性计算 阿里云云栖号 云栖号案例 云栖号直播