注意:
- 此文档仅适用于 CSP XML 版本,版本可登录后在 CSP 控制台首页查看。
- 此文档不适用于 POST object 的 HTTP 请求。
使用对象存储服务 CSP 时,可通过 RESTful API 对 CSP 发起 HTTP 匿名请求或 HTTP 签名请求,对于签名请求,CSP 服务器端将会进行对请求发起者的身份验证。
- 匿名请求:HTTP 请求不携带任何身份标识和鉴权信息,通过 RESTful API 进行 HTTP 请求操作。
- 签名请求:HTTP 请求时添加签名,CSP服务器端收到消息后,进行身份验证,验证成功则可接受并执行请求,否则将会返回错误信息并丢弃此请求。
云平台对象存储,基于密钥 HMAC (Hash Message Authentication Code) 的自定义 HTTP 方案进行身份验证。
签名使用场景
在 CSP 对象存储服务使用的场景中,对于需要对外发布类的数据,通常可将对象设置为公有读,私有写。
注意:
本文所描述的 API 请求签名,如果您使用 SDK 进行开发,则已包含在内。仅在您希望通过原始 API 进行二次开发时,需要根据本文所描述步骤进行操作。
在以下场景中,可对 API 请求进行多方面的安全防护:
- 请求者身份验证。通过访问者唯一 ID 和密钥确定请求者身份。
- 防止传输数据篡改。对数据加密并检验,保障传输内容完整性。
- 防止签名被盗用。对签名设置时效,且进行数据加密,避免签名盗用并重复使用。
签名流程
客户通过对 HTTP 请求进行签名,并将签名后的请求发送至云平台进行签名验证,具体流程如下图所示。
准备工作
APPID、SecretId 和 SecretKey。
在控制台云API密钥页面可获取。
确定开发语言:
支持但不限于 java、php 、c sharp、c++、 node.js、python,根据不同的开发语言,确定对应的 HMAC-SHA1、SHA1 函数。
签名内容
通过 RESTful API 对 CSP 发起的 HTTP 签名请求,使用标准的 HTTP Authorization 头部来传递,如下例所示:
PUT ?versioning HTTP/1.1
Host: bucket1-1254000000.cos.ap-beijing.myqcloud.com
Authorization: q-sign-algorithm=sha1&q-ak=AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&q-sign-time=1480932292;1481012298&q-key-time=1480932292;1481012298&q-header-list=host&q-url-param-list=versioning&q-signature=438023e4a4207299d87bb75d1c739c06cc9406bb
其中,签名内容由多个 key=value 对,通过 “&” 连接而成,格式如下:
q-sign-algorithm=sha1&q-ak=[SecretID]&q-sign-time=[SignTime]&
q-key-time=[KeyTime]&q-header-list=[SignedHeaderList]&
q-url-param-list=[SignedParameterList]&q-signature=[Signature]
键值描述
其中,组成签名内容的键值(key=value)描述如下:
键(key) | 值(value) | 描述 |
q-sign-algorithm | sha1 | 必填。 签名算法,目前仅支持 sha1,即为 sha1 。 |
q-ak | 参数[*SecretID*] | 必填。 帐户 ID,即 SecretId,在控制台云 API 密钥页面可获取。 如: AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 。 |
q-sign-time | 参数[*SignTime*] | 必填。 本签名的有效起止时间,通过 Unix 时间戳[注1] 描述起始和结束时间,以秒为单位,格式为 [*start-seconds*];[*end-seconds*]。 如: 1480932292;1481012298 。 |
q-key-time | 参数[*KeyTime*] | 必填。 与 q-sign-time 值相同。 |
q-header-list | 参数[*SignedHeaderList*] | 必填。 HTTP 请求头部。需从 key:value 中提取部分或全部 key,且 key 需转化为小写,并将多个 key 之间以字典顺序排序,如有多组 key,可用“;”连接。 如: HTTP 请求 “ Host: bucket1-1254000000.cos.ap-beijing.myqcloud.com Content-Type: image/jpeg ”,其 SignedHeaderList 为 content-type;host 。 |
q-url-param-list | 参数[*SignedParameterList*] | 必填。 HTTP 请求参数。需从 key=value 中提取部分或全部 key,且 key 需转化为小写,并将多个 key 之间以字典顺序排序,如有多组 key,可用“;”连接。 如: HTTP 请求 “ GET /?prefix=abc&max-keys=20 ” ,其则 SignedParameterList 为 max-keys;prefix 或者 prefix 。 |
q-signature | 参数[Signature] | 必填。 HTTP内容签名,请查看 Signature 计算 。 |
说明:
注1:关于q-sign-time 和 q-key-time
- Unix 时间戳是从格林威治时间1970 年 01 月 01 日 00 时 00 分 00 秒(北京时间 1970 年 01 月 01 日 08 时 00 分 00 秒)起至现在的总秒数。
- 结束时间戳需要大于起始时间戳,否则将会导致签名马上过期。
Signature 计算
Signature 的计算分为四个步骤:
- 对临时密钥的有效起止时间加密计算值 SignKey。
- 根据固定格式组合生成 HttpString。
- 加密 HttpString,并根据固定格式组合生成 StringToSign。
- 加密 StringToSign,生成Signature。
代码说明
其伪代码为:
SignKey = HMAC-SHA1(SecretKey,"[q-key-time]")
HttpString = [HttpMethod]\n[HttpURI]\n[HttpParameters]\n[HttpHeaders]\n
StringToSign = [q-sign-algorithm]\n[q-sign-time]\nSHA1-HASH(HttpString)\n
Signature = HMAC-SHA1(SignKey,StringToSign)
其中,在不同的开发语言环境,请用不同的语言规范更新代码,包含:
- 变量的定义与赋值,请根据所使用开发语言的规范更新。
- 伪函数 SHA1_FUNC,输出为 16 进制小写。请替换为所使用开发语言中对应的函数,如下表所示:
伪函数 php java HMAC-SHA1 hash_hmac HmacUtils.hmacSha1Hex SHA1-HASH sha1 DigestUtils.sha1Hex
代码实例(PHP)
如 php 开发环境中,以上代码为:
$SignKey = hash_hmac($SecretKey,"[q-key-time]")
$HttpString = [HttpMethod]\n[HttpURI]\n[HttpParameters]\n[HttpHeaders]\n
$StringToSign = [q-sign-algorithm]\n[q-sign-time]\nsha1($HttpString)\n
$Signature = hash_hmac($SignKey,$StringToSign)
参数说明
参数 | 说明 |
[q-key-time] | 必须与键值描述中所填写的 q-key-time 保持一致。 |
[HttpMethod] | HTTP请求方法。仅支持小写,即可为 get,post,put,delete,head,options。 如: HTTP 请求 “ GET /testfile ”,其 HttpMethod 为 get。 |
[HttpURI] | HTTP 请求 URI 部分。即从“/”虚拟根路径开始部分。 如: HTTP请求 “GET /testfile ”,其 HttpURI 为 /testfile 。 |
[HttpParameters] | HTTP 请求参数。即为 URI 中“?”之后由“&”连接的部分,需选取全部或部分 key=value,且 key 和value 均需转换为小写,多对 key=value 对之间以 “&” 相连接,并以字典顺序排序。 如: HTTP 请求 “ GET /?prefix=abc&max-keys=20 ”,其 HttpParameters 为 max-keys=20&prefix=abc 或 prefix=abc 。 注意: 所包含的 key=value 对中的 key 必须与键值描述中所填写的 q-url-param-list 中的 key 保持一致。 |
[HttpHeaders] | HTTP 请求头部。需选取全部或部分 key:value,并将其转化为 key=value 格式,且 key 需转换为小写,value 需进行 URLEncode 转换,多对 key=value 对之间以 “&” 相连接,并以字典顺序排序。 如: HTTP请求 “ Host: bucket1-1254000000.cos.ap-beijing.myqcloud.com Content-Type: image/jpeg ”,其 HttpHeaders 为 content-type=image%2Fjpeg&host=bucket1-1254000000.cos.ap-beijing.myqcloud.com 。 注意: 所包含的 key=value 对中的 key 必须与键值描述中所填写的 q-header-list 中的 key 保持一致。 |
[q-sign-algorithm] | sha1。目前仅支持 sha1 加密算法。 |
[q-sign-time] | 必须与键值描述中所填写的 q-sign-time 保持一致。 |
参数实例
参数 | 值 |
[q-key-time] | 1417773892;1417853898 |
[HttpMethod] | get |
[HttpURI] | /testfile |
[HttpParameters] | max-keys=20&prefix=abc |
[HttpHeaders] | host=bucket1-1254000000.cos.ap-beijing.myqcloud.com |
[q-sign-algorithm] | sha1 |
[q-sign-time] | 1417773892;1417853898 |
举例说明
如某用户希望使用 API 调用方式下载和上传对象,并对调用进行签名。
准备工作
通过登录云 API 密钥页面获取到其 APPID、SecretId 和 SecretKey,并确定开发语言,分别如下:
APPID | SecretId | SecretKey | 开发语言 |
1254000000 | AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | BQYIM75p8x0iWVFSIgqEKwFprpRSVHlz | php |
上传对象
需求:上传对象到存储桶 bucket1。
原始HTTP请求为:
PUT /testfile2 HTTP/1.1
Host: bucket1-1254000000.cos.ap-beijing.myqcloud.com
x-cos-content-sha1: 7b502c3a1f48c8609ae212cdfb639dee39673f5e
Hello world
签名后的HTTP请求为:
PUT /testfile2 HTTP/1.1
Host: bucket1-1254000000.cos.ap-beijing.myqcloud.com
x-cos-content-sha1: 7b502c3a1f48c8609ae212cdfb639dee39673f5e
Authorization: q-sign-algorithm=sha1&q-ak=AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&q-sign-time=1417773892;1417853898&q-key-time=1417773892;1417853898&q-header-list=host;x-cos-content-sha1;x-cos-storage-class&q-url-param-list=&q-signature=84f5be2187452d2fe276dbdca932143ef8161145
Hello world
各参数对应的值和描述如下:
键(key) | 值(value) | 备注 |
q-sign-algorithm | sha1 | 目前仅支持 sha1 签名算法。 |
q-ak | AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | SecretId 字段 |
q-sign-time | 1417773892;1417853898 | 2014/12/5 18:04:52 到 2014/12/6 16:18:18 |
q-key-time | 1417773892;1417853898 | 2014/12/5 18:04:52 到 2014/12/6 16:18:18 |
q-header-list | host;x-cos-content-sha1;x-cos-storage-class | HTTP 头部 key 的字典顺序排序列表 |
q-url-param-list | HTTP 参数列表为空 | |
q-signature | 84f5be2187452d2fe276dbdca932143ef8161145 | 通过代码计算所得 |
其中,q-signature 的计算代码为:
$signTime = '1417773892;1417853898';
$signKey = hash_hmac('sha1', $signTime, 'BQYIM75p8x0iWVFSIgqEKwFprpRSVHlz');
$httpString = "put\n/testfile2\n\nhost=bucket1-1254000000.cos.ap-beijing.myqcloud.com&x-cos-content-sha1=7b502c3a1f48c8609ae212cdfb639dee39673f5e&x-cos-storage-class=nearline\n";
$sha1edHttpString = sha1($httpString);
$stringToSign = "sha1\n$signTime\n$sha1edHttpString\n";
$signature = hash_hmac('sha1', $stringToSign, $signKey);
下载对象
需求:下载存储桶 bucket1 中的对象前 4 个字节。
原始HTTP请求为:
GET /testfile HTTP/1.1
Host: bucket1-1254000000.cos.ap-beijing.myqcloud.com
Range: bytes=0-3
签名后的 HTTP 请求为:
GET /testfile HTTP/1.1
Host: bucket1-1254000000.cos.ap-beijing.myqcloud.com
Range: bytes=0-3
Authorization: q-sign-algorithm=sha1&q-ak=AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&q-sign-time=1417773892;1417853898&q-key-time=1417773892;1417853898&q-header-list=host;range&q-url-param-list=&q-signature=4b6cbab14ce01381c29032423481ebffd514e8be
各参数对应的值和描述如下:
键(key) | 值(value) | 备注 |
q-sign-algorithm | sha1 | 目前仅支持 sha1 签名算法。 |
q-ak | AKIDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | SecretId 字段 |
q-sign-time | 1417773892;1417853898 | 2014/12/5 18:04:52 到 2014/12/6 16:18:18 |
q-key-time | 1417773892;1417853898 | 2014/12/5 18:04:52 到 2014/12/6 16:18:18 |
q-header-list | host;range | HTTP 头部 key 的列表 |
q-url-param-list | HTTP 参数列表为空 | |
q-signature | 4b6cbab14ce01381c29032423481ebffd514e8be | 通过代码计算所得 |
其中,q-signature的计算代码为:
$signTime = '1417773892;1417853898';
$signKey = hash_hmac('sha1', $signTime, 'BQYIM75p8x0iWVFSIgqEKwFprpRSVHlz');
$httpString = "get\n/testfile\n\nhost=bucket1-1254000000.cos.ap-beijing.myqcloud.com&range=bytes%3D0-3\n";
$sha1edHttpString = sha1($httpString);
$stringToSign = "sha1\n$signTime\n$sha1edHttpString\n";
$signature = hash_hmac('sha1', $stringToSign, $signKey);