跳到主要内容

在Header中包含签名

在Header中包含签名

用户可以在HTTP请求中增加Authorization(授权)的Header来包含签名(Signature)信息,表明这个消息已被授权。

Authorization字段计算的方法

"Authorization: COS " + AccessKeyId + ":" + Signature

Signature = base64(hmac-sha256(AccessKeySecret,
VERB + "\n”
+ Content-MD5 + "\n"
+ Content-Type + "\n"
+ Date + "\n"
+ CanonicalizedCOSHeaders
+ CanonicalizedResource))
  • AccessKeySecret表示签名所需的秘钥
  • VERB表示HTTP请求的Method,主要有PUT,GET,POST,HEAD,DELETE等
  • "\n"表示换行符
  • Content-MD5表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如果为空则表示不做检查
  • Content-Type表示请求内容的类型,如"application/octet-stream",也可以为空
  • Date表示此次操作的时间,且必须为HTTP1.1中支持的GMT格式,如"Sun, 22 Nov 2015 08:16:38 GMT"
  • CanonicalizedCOSHeaders表示以“x-cos-”为前缀的HTTP Header的组合;
  • CanonicalizedResource 表示用户想要访问的COS资源

其中,Date和CanonicalizedResource不能为空;如果请求中的DATE时间和COS服务器的时间差正负15分钟以上,COS服务器将拒绝该服务,并返回HTTP 403错误。

构建CanonicalizedCOSHeaders的方法

所有以"x-cos-"为前缀的HTTP Header被称为CanonicalizedCOSHeaders。它的构建方法如下:

  • 将所有以"x-cos-"为前缀的HTTP请求头的名字转换成小写字母。如"X-COS-Meta-Name: Demo"转换成"x-cos-meta-name: Demo"
  • 将上一步得到的所有HTTP请求头按照名字的字典序进行升序排列
  • 删除请求头和内容之间分隔符两端出现的任何空格。如"x-cos-meta-name: Demo"转换成:"x-cos-meta-name:Demo"
  • 将每一个头和内容用"\n"分隔符分隔拼成最后的CanonicalizedCOSHeaders

注意

 1. CanonicalizedCOSHeaders可以为空,无需添加最后的"\n"
2. 如果只有一个,则如'x-cos-meta-a\n',注意最后的"\n"
3. 如果有多个,则如‘x-cos-meta-a:a\nx-cos-meta-b:b\nx-cos-meta-c:c\n',注意最后的"\n"

构建CanonicalizedResource的方法

用户发送请求中想访问的COS目标资源被称为CanonicalizedResource。它的构建方法如下:

  • 将CanonicalizedResource置成空字符串("")
  • 放入要访问的COS资源:"/bucketname/ObjectName"(无ObjectName则CanonicalizedResource为"/bucketname/",如果同时也没有bucketname则为"/")
  • 如果请求的资源包括子资源(sub-resource),那么将所有的子资源按照字典序,从小到大排列并以&为分隔符生成资资源字符串。在CanonicalizedResource字符串尾添加”?”和子资源字符串。示例:/ObjectName?partNumber=PartNumber&uploadId=UploadId
  • COS目前支持的子资源(sub-resource)包括:acl,uploadId,partNumber,uploads,website,delete,location

计算签名注意事项

  1. 签名的字符串必须为UTF-8格式。含有中文字符的签名字符串必须先进行UTF-8编码,再与AccessKeySecret计算最终签名
  2. 签名的方法用RFC 2104中定义的HMAC-SHA256方法,其中Key为AccessKeySecret
  3. Content-Type和Content-MD5在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符“\n”代替
  4. 在所有非HTTP标准定义的Header中,只有以“x-cos-”开头的header,需要加入签名字符串;其他非HTTP标准header将被COS忽略
  5. 以“x-cos-”开头的Header在签名验证前需要符合以下规范:
    • Header的名字需要变成小写
    • Header按字典序自小到大排序
    • 分割Header的name和value的冒号前后不能有空格
    • 每个Header之后都有一个换行符“\n”,如果没有自定义Header,CanonicalizedCOSHeaders就设置为空

签名示例代码

假定用户想要往名称为mybucket的桶上传对象MyObject.txt,用户的密钥对为:

AccessKeyId = "YOUR_ACCESS_KEY_ID"
AccessKeySecret = "YOUR_ACCESS_KEY_SECRET"

那么,尚未加入Header签名Authorization的请求头为:

PUT /MyObject.txt HTTP/1.1
Host: mybucket.cos-cn-suzhou.chinac.com
Content-MD5: SDBGOERFM¥GDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=
Content-Type: text/plain
Date: Fri, 14 Nov 2015 19:47:08 GMT
X-COS-Meta-Author: my@gmail.com
X-COS-Magic: Chinac

通过Authorization字段计算的方法,以及CanonicalizedCOSHeaders和CanonicalizedResource构建方法,计算出签名Signature:

#! /usr/bin/python

import base64
import hmac
import hashlib

h = hmac.new(
"YOUR_ACCESS_KEY_SECRET",
"PUT\n" + # HTTP-VERB
"ODBGOERFMDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=\n" + # Content-MD5
"text/plain\n" + # Content-Type
"Fri, 14 Nov 2015 19:47:08 GMT\n" + # Date
"x-cos-magic:Chinac\n" + # CanonicalizedHeaders
"x-cos-meta-author:my@gmail.com\n" +
"/mybucket/MyObject", # CanonicalizedResource, MyObject need urlencode
hashlib.sha256)

print "Signature is " + base64.b64encode(h.digest())
# OUTPUT: Signature is fP7/XUUN6+8UmHJ9d9YGo8dpuRPeYlv3wX72A+kKM/A=

至此,根据Authorization头组成方式Authorization: COS " + AccessKeyId + ":" + Signature,能够拼接出最终的HTTP请求头,如下:

PUT /MyObject.txt HTTP/1.1
Host: mybucket.cos-cn-suzhou.chinac.com
Content-MD5: SDBGOERFM¥GDMzQTczRUY3NUE3NzA5QzdFNUYzMDQxNEM=
Content-Type: text/plain
Date: Fri, 14 Nov 2015 19:47:08 GMT
X-COS-Meta-Author: my@gmail.com
X-COS-Magic: Chinac
Authorization: COS dcbf4036e50a4135aaab604f729a8115:fP7/XUUN6+8UmHJ9d9YGo8dpuRPeYlv3wX72A+kKM/A=

细节说明

  1. 如果传入的AccessKeyId不存在或inactive,返回403 Forbidden。错误码:InvalidAccessKeyId
  2. 若用户请求头中Authorization值的格式不对,返回400 Bad Request。错误码:InvalidArgument
  3. COS所有的请求都必须使用HTTP1.1协议规定的GMT时间格式,错误的时间格式将返回失败
  4. 如果签名验证的时候,头中没有传入Date或者格式不正确,返回403 Forbidden错误。错误码:AccessDenied
  5. 传入请求的时间必须在COS服务器当前时间之后的15分钟以内,否则返回403Forbidden。错误码:RequestTimeTooSkewed
  6. 如果AccessKeyId是active的,但COS判断用户的请求发生签名错误,则返回403Forbidden,并在返回给用户的response中告诉用户正确的用于验证加密的签名字符串

常见问题

Content-MD5的计算方法

以消息内容为"123456789"来说,计算这个字符串的Content-MD5

正确的计算方式,以Python为例子:

>>> import hashlib
>>> hash = hashlib.md5()
>>> hash.update("0123456789")
>>> hash.hexdigest()
'781e5e245d69b566979b86e28d23f2c7'