• 关于

    js 中文日期转换

    的搜索结果

问题

【javascript学习全家桶】934道javascript热门问题,阿里百位技术专家答疑解惑

管理贝贝 2019-12-01 20:07:22 6202 浏览量 回答数 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:45 0 浏览量 回答数 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: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: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

回答

详细解答可以参考官方帮助文档 用户可以在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:45 0 浏览量 回答数 0

问题

程序员报错QA大分享(1)

问问小秘 2020-06-18 15:46:14 1684 浏览量 回答数 2

问题

【Java学习全家桶】1460道Java热门问题,阿里百位技术专家答疑解惑

管理贝贝 2019-12-01 20:07:15 27612 浏览量 回答数 19
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 企业建站模板