有奖捉虫:云通信与企业服务文档专题,速来> HOT
注意
您目前查阅的是历史版本 API 文档,已不再更新和维护,我们建议您查阅新版 API 文档
腾讯云对象存储提供多种语言 SDK,SDK 内置了生成签名的方法,详情请参见各语言 SDK 的生成签名章节。
注意
建议用户 使用临时密钥 生成签名,通过临时授权的方式进一步提高签名的安全性。申请临时密钥时,请遵循 最小权限指引原则,防止泄漏目标存储桶或对象之外的资源。
如果您一定要使用永久密钥,建议遵循 最小权限指引原则 对永久密钥的权限范围进行限制。

签名鉴权

为什么需要鉴权?

业务端购买腾讯云(对象存储)服务,来作为其业务组成的一部分(云存储或内容分发加速),并最终提供给用户。所以当用户访问腾讯云服务时,需要先征得业务端的“许可”。那么,用户如何才能向腾讯云证明自己已经得到“访问许可”了呢?
简单的说,腾讯云和业务端约定了一套规则,通过这套规则,业务端可以产生一个“钥匙”。当用户需要访问业务端购买的腾讯云服务时,业务端会将这个钥匙传递给用户,然后用户拿着这个钥匙去向腾讯云“证明”自己已经拿到了“访问许可”。腾讯云收到用户的请求后,会先鉴别“钥匙”是否有效,若有效,则允许访问云服务,若无效,则返回 Authorization 错误消息。
这套规则,就是腾讯云的“鉴权系统”,这把“钥匙”,就是下文要解释的“签名”。

签名有哪几种?

签名本质上是一个加密的字符串,目前在腾讯云中,分为多次有效签名单次有效签名
多次有效签名:签名中部分不绑定文件 fileid ,部分绑定文件 fileid ,开启token防盗链的下载、文件简单上传、文件分片上传可以绑定 fileid,同时支持前缀匹配。多次有效签名需要设置一个大于当前时间的有效期,有效期内此签名可多次使用,有效期最长可设置三个月。
单次有效签名:签名中绑定文件 fileid ,有效期必须设置为0,此签名只可使用一次,且只能应用于被绑定的文件或文件夹操作。

哪些场景需要用到签名?

腾讯云对象存储(COS)对签名的适用场景做了如下限制:
场景
适用签名
签名中是否需要绑定 fileid
下载(不开启 token 防盗链)
不验证签名
-
下载(开启 token 防盗链)
多次有效签名
可选
简单上传文件
多次有效签名
可选
分片上传文件
多次有效签名
可选
查询目录、文件属性
多次有效签名
创建目录
多次有效签名
删除目录、文件
单次有效签名
更新文件属性
单次有效签名
移动(重命名)文件
单次有效签名

如何使用签名来完成鉴权?

腾讯云对象存储(COS)通过签名来验证请求的合法性。业务端通过将签名授权给用户端,使其具备上传下载及管理指定资源的权限。
当用户使用 RESTful API 对腾讯云对象存储资源进行操作时,必须要在每个 Http/Https 请求的 Header 中填写 Host 和 Authorization,其中的 Authorization 参数,即为“签名算法”最终得到的 sign 字符串。
参数名称
必选
类型
描述
Host
String
文件云服务器域名,固定为[region].file.myqcloud.com
Authorization
String
用户的有效签名,用于鉴权
腾讯云对象存储目前提供了 COS 签名工具 供用户生成签名,如有需要可前往使用。

签名算法

腾讯云的各类 SDK 已经提供了标准的签名计算方法,业务端只需填写相关参数,即可得到签名字符串。用户也可以根据 RESTful API 自行计算签名。
对于签名的计算过程,可简单分为如下三个步骤:获取签名所需信息,拼接明文字符串,将明文字符串转化为签名

获取签名所需信息

生成签名所需信息包括项目 ID(App Id),空间名称(Bucket,文件资源的组织管理单元),项目的 Secret ID 和 Secret Key。获取这些信息的方法如下:
1. 登录腾讯云对象存储,进入对象存储空间;
2. 如开发者未创建空间,可添加空间,空间名称(Bucket)由用户自行输入;
3. 单击【获取 API 密钥】,获取 App Id,Secret ID 和 Secret Key。

拼接明文字符串 Original

明文字符串 Original 按照签名的类型可划分为“多次”和“单次”有效签名。
拼接多次有效签名串 multi_effect_signature :
Original = "a=[appid]&b=[bucket]&k=[SecretID]&e=[expiredTime]&t=[currentTime]&r=[rand]&f="
拼接单次有效签名串 once_signature :
Original = "a=[appid]&b=[bucket]&k=[SecretID]&e=[expiredTime]&t=[currentTime]&r=[rand]&f=[fileid]"
签名串中各字段含义如下:
字段
解释
a
开发者的项目 ID,接入对象存储服务创建空间时系统生成的唯一标识项目的 ID,即 App ID
b
空间名称 Bucket
k
项目的 Secret ID
t
当前时间戳,是一个符合 Unix Epoch 时间戳规范的数值,单位为秒
e
多次有效签名时,e 为签名的失效时刻,是一个符合Unix Epoch时间戳规范的数值,单位为秒。e 的计算方式为 e = t + 签名有效时长。签名有效时长最大取值为7776000(90天);单次签名时,e 必须设置为0
r
随机串,无符号10进制整数,用户需自行生成,最长 10 位
f
fileid ,唯一标识存储资源的相对路径。格式为 /appid/bucketname/dirname/[filename],并且需要对其中非 '/' 字符进行 UrlEncode 编码。 当操作对象为 文件夹时,filename 缺省。filename 中要包含文件后缀名。
注意
当签名类型需要绑定 fileid 时,f 字段请按要求赋值。
拼接单次有效签名的签名串时,过期时间 e 必须设置为0,以保证此签名只能针对固定资源使用一次。
拼接多次有效签名的签名串时,过期时间 e 的单位为秒,不同编程语言获得的系统 Unix 时间戳单位可能有所差异(例如 Java 是毫秒),但都请转化为秒。
多次/单次有效签名的具体适用场景参见本文章节哪些场景需要用到签名?

将明文字符串转化为签名

拼接好签名的明文字符串 Original 后,用已经获取的 SecretKey 对明文串进行 HMAC-SHA1 加密,得到 SignTmp:
SignTmp = HMAC-SHA1(SecretKey, Original)
将密文串 SignTmp 放在明文串 Origin 前面,拼接后进行 Base64Encode 算法,得到最终的签名 Sign:
Sign = Base64 (append(SignTmp, Original))
注意
此处使用的是标准的 Base64 编码,不是 urlsafe 的 Base64 编码。
由于使用了 HMAC 算法,计算 SignTmp 的结果为二进制字符串,因此建议将算法写在同一函数中实现。单独输出 SignTmp 可能导致拼接后的字符串有误。

示例

本节介绍生成签名的算法实例,实例中使用 PHP 语言(若开发者使用其他开发语言,请使用对应的函数)。

获取签名所需信息

获取得到的签名所需信息如下
项目 ID:200001
空间名称 Bucket:newbucket
Secret ID:AKID****************
Secret Key:bLcPnl88WU Secret ID:AKID****RhSePfPdOfSruK

拼接签名串

拼接的多次有效签名串 multi_effect_signature 如下:
a=200001&b=newbucket&k=AKID****************&e=1437995704&t=1437995644&r=2081660421&f=
拼接的单次有效签名串 once_signature 如下:
a=200001&b=newbucket&k=AKID****************&e=0&t=1437995645&r=1166710792&f=/200001/newbucket/tencent_test.jpg
$appid = "200001";
$bucket = "newbucket";
$secret_id = "AKID****************";
$secret_key = "bLcPnl88WU****RhSePfPdOfSruK";
$expired = time() + 60;
$onceExpired = 0;
$current = time();
$rdm = rand();
$fileid = "/200001/newbucket/tencent_test.jpg";

$multi_effect_signature = 'a='.$appid.'&b='.$bucket.'&k='.$secret_id.'&e='.$expired.'&t='.$current.'&r='.$rdm.'&f=';

$once_signature=
'a='.$appid.'&b='.$bucket.'&k='.$secret_id.'&e='.$onceExpired.'&t='.$current.'&r='.$rdm.'&f='.$fileid;

生成签名

$multi_effect_signature = base64_encode(hash_hmac('SHA1', $multi_effect_signature, $secret_key, true).$multi_effect_signature);

$once_signature = base64_encode(hash_hmac('SHA1',$once_signature,$secret_key, true).$once_signature);

echo $multi_effect_signature."\\n";

echo $once_signature."\\n";
最终得到的多次有效签名为:v6+um3VE3lxGz97PmnSg6+/V9PZhPTIwMDAwMSZiPW5ld2J1Y2tldCZrPUFLSURVZkxVRVVpZ1FpWHFtN0NWU3NwS0pudWFpSUt0eHFBdiZlPTE0NzA3MzcwMDAmdD0xNDcwNzM2OTQwJnI9NDkwMjU4OTQzJmY9
单次有效签名为: CkZ0/gWkHy3f76ER7k6yXgzq7w1hPTIwMDAwMSZiPW5ld2J1Y2tldCZrPUFLSURVZkxVRVVpZ1FpWHFtN0NWU3NwS0pudWFpSUt0eHFBdiZlPTAmdD0xNDcwNzM2OTQwJnI9NDkwMjU4OTQzJmY9LzIwMDAwMS9uZXdidWNrZXQvdGVuY2VudF90ZXN0LmpwZw==