签名机制

本文主要介绍API调用时的签名机制。

BatchCompute 通过使用 Access Key ID/ Access Key Secret 方法来验证某个请求的发送者身份。Access Key ID 用于标示用户,Access Key Secret 是用户用于加密签名字符串和 BatchCompute 用来验证签名字符串的密钥,其中 Access Key Secret 必须保密,只有用户和 BatchCompute 知道。

当用户想以个人身份向 BatchCompute 发送请求时,需要首先将发送的请求按照 BatchCompute 指定的格式生成签名字符串;然后使用 Access Key Secret 对签名字符串进行加密产生验证码。 BatchCompute 收到请求以后,会通过 Access Key ID 找到对应的 Access Key Secret,以同样的方法提取签名字符串和验证码,如果计算出来的验证码和提供的一样即认为该请求是有效的;否则,BatchCompute 将拒绝处理这次请求,并返回 HTTP 400 错误。

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

Authorization 字段计算方法如下:

Authorization: "acs " + Access Key Id + ":" + Signature

Signature = base64(hmac-sha1(AccessKeySecret,
            + VERB + "\n" 
            + ACCEPT + "\n"
            + CONTENT-MD5 + "\n" 
            + CONTENT-TYPE + "\n" 
            + DATE + "\n" 
            + CanonicalizedBatchComputeHeaders
            + CanonicalizedResource))
  • AccessKeySecret 表示签名所需的密钥

  • VERB 表示 HTTP 请求的 Method,主要有 PUT,GET,POST,HEAD,DELETE 等(大写)

  • CONTENT-MD5 表示请求内容数据的 MD5 值,详情参看(十六进制序列,字母小写)

  • ACCEPT 表示 HTTP 请求期望接受的类型

  • CONTENT-TYPE 表示请求内容的类型

  • DATE 表示此次操作的时间,且必须为 HTTP1.1 中支持的 GMT 格式

  • CanonicalizedOSSHeaders 表示以“x-acs-”为前缀的 http header 的组合

  • CanonicalizedResource 表示 API 想要访问的 BatchCompute 资源

其中,CanonicalizedBatchComputeHeaders 表示 HTTP 中的 object meta 组合。CanonicalizedResource 表示 API 想要访问的 BatchCompute 资源。DATE 和 CanonicalizedResource 不能为空。如果请求中的 DATE 时间和 BatchCompute 服务器的时间差正负 15 分钟以上,BatchCompute 服务器将拒绝该服务,并返回 HTTP 400 错误。其他字段请参考公共请求头参数。

构建 CanonicalizedBatchComputeHeaders 的方法:

所有以“x-acs-”为前缀的 HTTP Header 被称为 CanonicalizedBatchComputeHeaders,它的构建方法如下:

  1. 将所有以“x-acs-”为前缀的 HTTP 请求头的名字转换成小写字母。如“X-Acs-Meta-Name: TaoBao”转换成“x-acs-meta-name: TaoBao”;

  2. 将上一步得到的所有 HTTP 请求头按照字典序进行升序排列;

  3. 如果有相同名字的请求头,则根据标准 RFC 2616, 4.2 章进行合并(两个值之间只用逗号分隔)。如有两个名为“x-acs-meta-name”的请求头,对应的值分别为“TaoBao”和“Alipay”,则合并后为:“x-acs-meta-name:TaoBao,Alipay”;

  4. 删除请求头和内容之间分隔符两端出现的任何空格。如“x-acs-meta-name: TaoBao,Alipay”转换成:“x-acs-meta-name:TaoBao,Alipay”;

  5. 将所有的头和内容用“\n”分隔符分隔拼成最后的CanonicalizedBatchComputeHeader。

构建CanonicalizedResource的方法:

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

  1. 将 CanonicalizedResource 置成空字符串(“”);

  2. 放入要访问的 BatchCompute 资源:“/ResourceName/ResourceId”(无 ResourceId 则不填);

  3. 如果请求的资源包括子资源(sub-resource) ,那么将所有的子资源按照字典序,从小到大排列并以“&”为分隔符生成子资源字符串。在 CanonicalizedResource 字符串尾添加“?”和子资源字符串。此时的 CanonicalizedResource 例子如:/jobs/(id)/tasks?Marker=(Marer)&MaxItemCount=(MaxItemCount)。

例如,需要签名以下信息:

PUT /jobs/job-000000005645B53B0000AEA300000001 HTTP/1.0
Content-Md5: 900150983cd24fb0d6963f7d28e17f72
Content-Type: application/json
Date: Thu, 17 Nov 2005 18:49:58 GMT
Host: batchcompute.cn-qingdao.aliyuncs.com
x-acs-signature-method: HMAC-SHA1
x-acs-signature-version: 1.0

其中,Access Key ID 是:“44CF******”, Access Key Secret 是“Otxr******”,可用以下方法签名(Signature):

python示例代码:

import base64
import hmac
import sha
h = hmac.new("Otxr******",
             "PUT\n900150983cd24fb0d6963f7d28e17f72\napplication/json\nThu, 17 Nov 2005 18:49:58 GMT\nx-acs-signature-method:HMAC-SHA1\nx-acs-signature-version:1.0\n/jobs/job-000000005645B53B0000AEA300000001", sha)
base64.encodestring(h.digest()).strip()

签名(Signature)计算结果应该为“26NBxoKdsyly4EDv6inkoDft/yA=”, 然后加上 Authorization 头来组成最后需要发送的消息:

PUT /jobs/job-000000005645B53B0000AEA300000001 HTTP/1.0
Authorization: acs 44CF******: 26NBxoKdsyly4EDv6inkoDft/yA=
Content-Md5: 900150983cd24fb0d6963f7d28e17f72
Content-Type: application/json
Date: Thu, 17 Nov 2005 18:49:58 GMT
Host: batchcompute.cn-qingdao.aliyuncs.com
x-acs-signature-method: HMAC-SHA1
x-acs-signature-version: 1.0

在计算签名头的时候请遵循如下规则:

  1. 用来签名的字符串必须为 UTF-8 格式。含有中文字符的签名字符串必须先进 UTF-8 编码,再与 Access Key Secret 计算最终签名。

  2. 签名的方法用 RFC 2104 中定义的 HMAC-SHA1 方法,其中 Key 为 Access Key Secret。

  3. Content-Type 和 Content-MD5 在请求中不是必须的,但是如果请求需要签名验证,空值的话以换行符“\n”代替。

  4. 在所有非 HTTP 标准定义的 header 中,只有以“x-acs-”开头的 header,需要加入签名字符串;其他非 HTTP 标准 header 将被忽略。

  5. 以“x-acs-”开头的 head 在签名验证前需要符合以下规范:

    • head 的名字需要变成小写。

    • head 按字典序自小到大排序。

    • 分割 head name 和 value 的冒号前后不能有空格。

    • 每个Head之后都有一个换行符“\n”,如果没有 Head,CanonicalizedBatchComputeHeaders 就设置为空。

备注:BatchCompute 所有的请求都必须使用 HTTP 1.1 协议规定的 GMT 时间格式 。其中,日期的格式有三种:

date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)

date2 = 2DIGIT “-“ month “-“ 2DIGIT; day-month-year (e.g., 02-Jun-82)

date3 = month SP ( 2DIGIT or ( SP 1DIGIT )); month day (e.g., Jun 2) 【注意“2”前面有两个空格】

述这三种日期格式中,“天”所占位数都是“2 DIGIT”。因此,“Jun 2”、“2 Jun 1982”和“2-Jun-82”都是非法日期格式。