请求签名

最近更新时间:2019-05-31 10:51:35

请求签名

当用户请求KS3时,可以使用AccessKey和SecretKey对请求做签名,当KS3收到带签名信息的请求之后,将使用相同的算法验证签名,如果发现签名不一致,KS3将会返回403给用户。如果KS3验证签名一致,且AccessKey对应的用户有权限操作请求的资源,则请求成功,否则KS3返回403。 如果用户请求KS3时,在请求中没有携带签名信息,那么KS3认为该请求是匿名的。当KS3接收到匿名请求时,如果发现用户请求的资源不允许匿名请求,将会返回403。

KS3提供了可视化签名工具,方便客户调试签名错误,快速定位问题。

1. 通过 HTTP 请求 Header 发送签名

方法: 在请求中加入名为 Authorization 的 Header,值为签名值。如下:

Authorization: KSS P3UPCMORAFON76Q6RTNQ:vU9XqPLcXd3nWdlfLWIhruZrLAM=

签名(Authorization)计算方法:

Authorization = “KSS YourAccessKey:Signature”

Signature = Base64(HMAC-SHA1(YourSecretKey, UTF-8-Encoding-Of( StringToSign ) ) );

StringToSign = HTTP-Verb + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedKssHeaders+
CanonicalizedResource;

Content-MD5, Content-Type, CanonicalizedKssHeaders可为空, 若为空,则使用空字符串("")替代, HTTP-Verb、Date和CanonicalizedResource不能为空

  • HTTP-Verb 表示请求的方法,如:GET\PUT\POST\DELETE等
  • Content-MD5 表示请求内容数据的MD5值, 使用Base64编码。当请求的header中包含Content-MD5时,需要在StringToSign中包含,否则用("")替代。 注意:Content-MD5的算法为先对数据做MD5摘要,再将MD5摘要做Base64编码。中间不需要做HEX编码,由于部分语言或工具包的MD5是默认做HEX编码的,所以当MD5算出来的结果为HEX编码的,首先需要对算出来的结果做HEX解码,然后再做Base64编码。详解RFC2616
  • Content-Type 表示请求内容的类型,取HTTP header中的Content-Type
  • Date 表示此次操作的时间,且必须为 HTTP1.1 中支持的 GMT 格式。取HTTP Header中的Date,如果该时间与KS3服务端时间相差15分钟以外,将导致KS3返回403。比如:Wed, 17 Feb 2012 15:31:56 GMT

    注意: 有的客户端不支持发送Date请求头。这种情况下,计算签名时需要保持Date字段的同时,在CanonicalizedKssHeaders中加入x-kss-date,格式与Date一致。发送请求时,需要添加x-kss-date请求头。详见示例

  • CanonicalizedKssHeaders 表示HTTP请求中的以x-kss开头的Header组合,详见CanonicalizedKssHeaders计算方法
  • CanonicalizedResource 表示用户访问的资源,详见CanonicalizedResource的计算方法

CanonicalizedKssHeaders计算方法

计算方法如下

  1. 先选出所有以x-kss-开头的 HTTP 请求Header,并把Header Name全部转成小写。如: X-KSS-Meta-Myname: Jack把Header Name转成小写后为x-kss-meta-myname: Jack
  2. 将这些Header按Header Name的名字的字典序进行升序排列
  3. 删除请求头和内容之间分隔符两端出现的任何空格。如x-kss-meta-myname: Jack转换为:x-kss-meta-myname:Jack
  4. 将这些Header Name, Header Value对使用"\n"分隔符连接在一起。

注意:

  • CanonicalizedKssHeaders为空,无需添加最后的\n
  • 如果只有一个,则需要在最后添加\n,例如:x-kss-meta-yourname:Lee\n
  • 如果有多个,则使用使用"\n"分隔符连接在一起,并且在最后添加\n,例如:x-kss-meta-myname:Jack\nx-kss-meta-yourname:Lee\n
  • 如果客户端不支持发送 Date 请求头时,在计算CanonicalizedKssHeaders时必须增加 x-kss-date 请求头。详见示例

CanonicalizedResource的计算方法

CanonicalizedResource 代表了请求的目标资源,结构如下:

/[BucketName/[ObjectKey[?SubResource]]]
  • BucketName:用户请求的Bucket名称。

  • ObjectKey:用户请求的Object名称,需要对Object名称做URL编码。

  • SubResource:用户请求的子资源。把URL参数中的"acl","lifecycle","location","logging","notification","partNumber","policy","requestPayment","torrent","uploadId","uploads","versionId","versioning","versions","website","delete","thumbnail","cors","queryadp","adp","asyntask","querytask","domain","response-content-type","response-content-language","response-expires","response-cache-control","response-content-disposition","response-content-encoding"筛选出来,将这些查询字符串及其请求值(不做URL编码的请求值)按照字典序,从小到大排列,以&为分隔符排列,即可得到SubResource。

计算方法如下:

  1. CanonicalizedResource="/"

  2. 如果BucketName不为空,则 CanonicalizedResource = CanonicalizedResource + BucketName + "/"
  3. 如果ObjectKey不为空,则 CanonicalizedResource = CanonicalizedResource + ObjectKey

  4. 替换CanonicalizedResource中的双斜杠("//")为"/%2F"

  5. 如果SubResource不为空,则CanonicalizedResource = CanonicalizedResource + "?" + SubResource

1. 计算签名的例子:

示例中的ObjectKey为经过URL编码的ObjectKey

PUT /{BucketName}/{ObjectKey} HTTP/1.0
Content-Md5: 1B2M2Y8AsgTpgAmY7PhCfg==
Content-Type: text/html
Content-Length: 1024
Date: Wed, 17 Feb 2012 15:31:56 GMT
Host: kss.ksyun.com

假设 SecretKey 为:Ik90eHJ6eElzZnBGakE3U3dQeklMd3k,其签名算法为:

import base64
import hmac
from hashlib import sha1
h = hmac.new("Ik90eHJ6eElzZnBGakE3U3dQeklMd3k", "PUT\n1B2M2Y8AsgTpgAmY7PhCfg==\ntext/html\nWed, 17 Feb 2012 15:31:56 GMT\n/{BucketName}/{ObjectKey}", sha1)
Signature = base64.encodestring(h.digest()).strip()

2. 客户端不支持发送Date请求头的例子

计算签名时需要保持Date字段的同时,在CanonicalizedKssHeaders中加入x-kss-date,格式与Date一致。发送请求时,需要添加x-kss-date请求头。示例中的ObjectKey为经过URL编码的ObjectKey。

PUT /{BucketName}/{ObjectKey} HTTP/1.0
Content-Md5: 1B2M2Y8AsgTpgAmY7PhCfg==
Content-Type: text/html
Content-Length: 1024
Date: Wed, 17 Feb 2012 15:31:56 GMT
Host: kss.ksyun.com
x-kss-date: Wed, 17 Feb 2012 15:31:56 GMT

假设 SecretKey 为:Ik90eHJ6eElzZnBGakE3U3dQeklMd3k,其签名算法为:

import base64
import hmac
from hashlib import sha1
h = hmac.new("Ik90eHJ6eElzZnBGakE3U3dQeklMd3k", "PUT\n1B2M2Y8AsgTpgAmY7PhCfg==\ntext/html\nWed, 17 Feb 2012 15:31:56 GMT\nx-kss-date:Wed, 17 Feb 2012 15:31:56 GMT\n/{BucketName}/{ObjectKey}", sha1)
Signature = base64.encodestring(h.digest()).strip()

3. 通过 URL QueryString 发送签名

携带签名的URL示例:

https://kss.ksyun.com/{BucketName}/{ObjectKey}?KSSAccessKeyId=VSDNT6SHFNDWBXYZRS3A&Expires=1435550417&Signature=a2JnaLMuN%2FWmcKL%2FW4aibMCa4BY%3D

KSSAccessKeyId为用户的AccessKey

Expires为该链接的过期时间,使用Unix_Time表示

Signature的计算法同上,只是把Date换成Expires值

金山云,开启您的云计算之旅

注册有礼