PHP生成腾讯云COS请求签名
COS和请求签名是什么
COS 是腾讯云对象存储的缩写及简称,请求签名是第三方在调用COS相关接口时需要按需提供的、经过特定算法创建而成的一组字符串信息,将唯一的标识当前第三方身份,提供通信双方的身份识别,只有有效的签名COS才会提供服务
目标
使用 PHP 创建 COS 接口所需要的请求签名,与官方文档给出的示例做比较,验证算法的正确性
认识请求签名
先来看一条官方文档给出的请求签名的样子
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为固定值
- 一共有7对key=value
- sha1也是参数,但截止到官方发文只支持sha1,因此可以直接赋值
- SignedHeaderList、SignedParameterList、Signature三个value需要通过算法生成
键值对的具体描述参见官方文档。
逐个击破
请求签名一共需要7个值,下面一一讲解,各个击破
q-sign-algorithm
签名算法,官方目前仅支持 sha1,因此直接给值即可
q-ak
账户ID,即用户的 SecretId,可以在控制台 云API密钥 页面获取
q-sign-time
当前签名的有效起止时间,Unix时间戳格式,英文半角分号 ;
分割,格式如 1480932292;1481012298
q-key-time
与 q-sign-time 值相同
q-header-list
个人理解,由HTTP请求头组成,取全部或部分请求头,将 key:value
形式的请求项的 key 部分取出,转化小写,多个 key 按字典排序,以字符 ;
连接,最终组成字符串
如原始请求头有两个:
Host:bucket1-1254000000.cos.ap-beijing.myqcloud.com
Content-Type:image/jpeg
key 就是 Host 和 Content-Type,经过运算后输出 content-type;host
q-url-param-list
个人理解,由HTTP请求参数组成,取全部或部分请求参数,将 key=value
形式的请求参数的 key 部分取出,转化小写,多个 key 按字典排序,以字符 ;
连接,最终组成字符串
如原始HTTP请求为:
GET /?prefix=abc&max-keys=20
key 就是 prefix 和 max-keys,经过运算后输出 max-keys;prefix
,如果请求没有参数比如 put、post,此处即为空
q-signature
根据HTTP内容计算签名,算法由COS提供,只需按要求给值
官方示例及参照结果
在开始编写逻辑之前,先看一下官方示例给出的参考值,以及经过计算后的结果,以便和自己开发的逻辑进行结果比对
HTTP原始请求,也可以理解为计算签名前或不需要签名时的HTTP请求:
PUT /testfile2 HTTP/1.1
Host: bucket1-1254000000.cos.ap-beijing.myqcloud.com
x-cos-content-sha1: 7b502c3a1f48c8609ae212cdfb639dee39673f5e
x-cos-storage-class: standard Hello world
计算签名后应该得到的HTTP请求:
PUT /testfile2 HTTP/1.1
Host: bucket1-1254000000.cos.ap-beijing.myqcloud.com
x-cos-content-sha1: 7b502c3a1f48c8609ae212cdfb639dee39673f5e
x-cos-storage-class: standard
Authorization: q-sign-algorithm=sha1&q-ak=AKIDQjz3ltompVjBni5LitkWHFlFpwkn9U5q&> 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=14e6ebd7955b0c6da532151bf97045e2c5a64e10 Hello world
结论:算法如果能得到 Authorization 后的那一串字符串即为正确
准备工作
来看一下(官方提供的)用户信息以及HTTP信息:
- SecretId:AKIDQjz3ltompVjBni5LitkWHFlFpwkn9U5q
- SecretKey:BQYIM75p8x0iWVFSIgqEKwFprpRSVHlz
- 签名有效起始时间:1417773892
- 签名有效停止时间:1417853898
- HTTP原始请求头:根据上一节示例不难得到HTTP原始请求有三项内容 Host、x-cos-content-sha1 和 x-cos-storage-class
- HTTP请求参数:是 PUT 请求,没有 ? 参数
计算签名
将准备工作中的各项参数带入请求签名规则,不难就可以得到结果,如下表:
键(key) | 值(value) | 备注 |
---|---|---|
q-sign-algorithm | sha1 | 目前仅支持 sha1 签名算法 |
q-ak | AKIDQjz3ltompVjBni5LitkWHFlFpwkn9U5q | 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 | 14e6ebd7955b0c6da532151bf97045e2c5a64e10 | 通过代码计算所得 |
但 q-signature 怎么来的?
刚才说到,q-signature 也需要特定算法计算得来,下面就说明如何计算
计算请求签名
先看代码:
/**
* 计算签名
* secretId、secretKey 为必需参数,qSignStart、qSignEnd为调试需要,测试通过后应取消,改为方法内自动创建
*/
function get_authorization( $secretId, $secretKey, $qSignStart, $qSignEnd, $fileUri, $headers ){
/*
* 计算COS签名
* 2018-05-17
* author:cinlap <cash216@163>
* ref:https://cloud.tencent.com/document/product/436/7778
*/
$qSignTime = "$qSignStart;$qSignEnd"; //unix_timestamp;unix_timestamp
$qKeyTime = $qSignTime;
$header_list = get_q_header_list($headers);
//如果 Uri 中带有 ?的请求参数,该处应为数组排序后的字符串组合
$url_param_list = '';
//compute signature
$httpMethod = 'put';
$httpUri = $fileUri;
//与 q-url-param-list 相同
$httpParameters = $url_param_list;
//将自定义请求头分解为 & 连接的字符串
$headerString = get_http_header_string( $headers );
// 计算签名中的 signature 部分
$signTime = $qSignTime;
$signKey = hash_hmac('sha1', $signTime, $secretKey);
$httpString = "$httpMethod\n$httpUri\n$httpParameters\n$headerString\n";
$sha1edHttpString = sha1($httpString);
$stringToSign = "sha1\n$signTime\n$sha1edHttpString\n";
$signature = hash_hmac('sha1', $stringToSign, $signKey);
//组合结果
$authorization = "q-sign-algorithm=sha1&q-ak=$secretId&q-sign-time=$qSignTime&q-key-time=$qKeyTime&q-header-list=$header_list&q-url-param-list=$url_param_list&q-signature=$signature";
return $authorization;
}
为了测试,该方法参数应该是多过需要了,前六个参数是已经给出的,是来自用户的,因此直接赋值即可得到下边字符串:
$authorization = "q-sign-algorithm=sha1&q-ak=$secretId&q-sign-time=$qSignTime&q-key-time=$qKeyTime...
$header_list 这个值要符合 q-header-list
规则因此需要计算,逻辑是上文已经描述,是从既定的请求项中抽出 key 组成有序字符串,代码如下:
/**
* 按COS要求对header_list内容进行转换
* 提取所有key
* 字典排序
* key转换为小写
* 多对key=value之间用连接符连接
*
*/
function get_q_header_list($headers){
if(!is_array($headers)){
return false;
}
try{
$tmpArray = array();
foreach( $headers as $key=>$value){
array_push($tmpArray, strtolower($key));
}
sort($tmpArray);
return implode(';', $tmpArray);
}
catch(Exception $error){
return false;
}
}
$url-param-list 上面讲过,这个值是HTTP请求参数,对于 PUT 方法没有 ? 参数,自然值为空,所以代码中“偷懒”直接给了空字符串。
Signature 的计算和需要小心的地方
官方已经给出了完整的算法,PHP 甚至还有写好的代码,应该是很幸福了(但!由于看官方文档看的头晕还是踩了坑,随后一起说明),先看一下 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)
再看一下 Signature 的完整算法:
$signTime = $qSignTime;
$signKey = hash_hmac('sha1', $signTime, $secretKey);
$httpString = "$httpMethod\n$httpUri\n$httpParameters\n$headerString\n";
$sha1edHttpString = sha1($httpString);
$stringToSign = "sha1\n$signTime\n$sha1edHttpString\n";
$signature = hash_hmac('sha1', $stringToSign, $signKey);
- $signTime:很简单,起止时间组成的字符串,从上文拿来直接用
- $signKey:HMAC-SHA1 算法直接计算即可
- $httpString:四个部分组成需要分开说
- $httpMethod:HTTP请求方法,小写,比如 put、get
- $httpUri:HTTP请求的URI部分,从“/”虚拟根开始,如
/testfile
说明在存储桶根目录下创建一个叫testfile
的文件,/image/face1.jpg
说明在根目录/image目录下建立一个叫face1.jpg
的文件,至于是不是图片文件,不管 - $httpParameters:这是第一个需要小心的地方。由HTTP原始请求参数组成,即请求 URI 中 ? 后面的部分,本例调用的是 PUT Object 接口,因此为空。如果不为空,需要把请求参数每一项的 key 和 value 均转换小写,多对 key=value 按字典排序并以 & 相连接
- $headerString:这是第二个需要小心的地方,由 HTTP 原始请求头组成,根据请求头,选择全部或部分请求头,把每项的key都转换为小写,把value都进行URLEncode转换,每项格式都改为key=value,然后按照key进行字典排序,最后把它们用连接符 & 组成字符串。这是我整理的逻辑,代码如下:
/**
* 按COS要求从数组中获取 Signature 中 [HttpString] 内容
* 标准格式 key=value&key=value&...
* 数组元素按键字典排序 *
* key转换为小写
* value进行UrlEncode转换
* 转换为key=value格式
* 多对key=value之间用连接符连接
*
*/
function get_http_header_string($headers){
if(!is_array($headers)){
return false;
}
try{
$tmpArray = array();
foreach($headers as $key => $value){
$tmpKey = strtolower($key);
$tmpArray[$tmpKey] = urlencode($value);
}
ksort($tmpArray);
$headerArray = array();
foreach( $tmpArray as $key => $value){
array_push($headerArray, "$key=$value");
}
return implode('&', $headerArray);
}
catch(Exception $error){
return false;
}
}
为什么要小心?
HTTP原始请求头和请求参数用在了四个地方,分别是请求签名里的 q-header-list 和 Signature 里的 HttpHeaders——两者都用到了HTTP原始请求头;请求签名里的 q-url-param-list 和 Signature 里的 HttpParameters——两者都用到了HTTP请求参数。一定要保证HTTP请求头和请求参数所选用的数量和对象一致
- 相同:生成 q-header-list 的HTTP请求头数量和成员要和生成 HttpHeaders 的相同,生成 q-url-param-list 的HTTP请求参数数量和成员要和生成 HttpParameters 的相同
- 不同:q-header-list 和 q-url-param-list 只取 key 部分,HttpHeaders 和 HttpParameters 取 key 和 value 部分
输出结果和校验
至此,请求签名中7个值都有了,有的是来自用户信息,有的需要计算,需要计算的上面也给出了所有的计算方法和为什么如此计算的个人理解。最后只需要按照官方要求进行输出即可。看一下
PHP生成腾讯云COS请求签名的更多相关文章
- 微信小程序/网站 上传图片到腾讯云COS
COS简介: 腾讯云提供的一种对象存储服务,供开发者存储海量文件的分布式存储服务.可以将自己开发的应用的存储部分全部接入COS的存储桶中,有效减少应用服务器的带宽,请求等.个人也可以通过腾讯云账号免费 ...
- Go操作腾讯云COS对象存储的简单使用案例
准备环境 安装Go环境 Golang:用于下载和安装 Go 编译运行环境,请前往 Golang 官网进行下载 安装SDK go get -u github.com/tencentyun/cos-go- ...
- Nginx反向代理腾讯云COS的一个坑
版权声明:本文由黄希彤 原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/668639001484812620 来源:腾云 ...
- 搭建markdown图床-腾讯云COS
背景介绍 书写markdown笔记时,如何处理图片,实在是有些棘手的问题.每一张图都保存在当前文件夹? 每张图都自己重命名?每次上传到cnblogs博客都需要一张一张拖动?markdown已经非常成功 ...
- PHP 腾讯云cos使用之我见
因为某些人的原因,本文从新改名发布一遍. 原名称:tp5 -- 腾讯云cos简单使用 原文链接:https://www.cnblogs.com/YFYQ/p/10840050.html 因项目需要,本 ...
- tp5 -- 腾讯云cos简单使用
因项目需要,本来是需要对接阿里云oss,但因客户错误将云存储买成腾讯云cos,因此简单做了个对象上传使用 首先下载cos的sdk: 三种方式在文档上面都有介绍 SDK 安装有三种方式:Composer ...
- 腾讯云COS对象存储的简单使用
叮当哥之前买了一年的腾讯云服务器,昨日偶然发现腾讯云送了叮当哥半年的cos对象存储服务器,于是就撸起袖子传了几张珍藏的高清大图上去,现将其上传的简单使用步骤总结一波(其它操作参加官方SDK文档API) ...
- 腾讯云COS对象存储
一.腾讯云COS 腾讯云对象存储 COS 是一种存储海量数据的分布式存储服务.COS 提供了多种对象的存储类型:标准存储.低频存储.归档存储. 二.为什么要使用TA 便宜: 个人用户有6个月的免费使用 ...
- 腾讯云COS对象存储 Web 端直传实践(JAVA实现)
使用 腾讯云COS对象存储做第三方存储云服务,把一些文件都放在上面,这里主要有三中实现方式:第一种就是在控制台去设置好,直接上传文件.第二种就是走服务端,上传文件,就是说,上传文件是从服务端去上传上去 ...
随机推荐
- TCP中的MSS解读(转)
本文摘录自TCP中的MSS解读. MSS 是TCP选项中最经常出现,也是最早出现的选项.MSS选项占4byte.MSS是每一个TCP报文段中数据字段的最大长度,注意:只是数据部分的字段,不包括TCP的 ...
- XMPP客户端库Smack
原文博客地址:http://blog.csdn.net/chszs/article/details/41576877
- Mybatis源码之CallableStatementHandler
/** * @author Clinton Begin */ public class CallableStatementHandler extends BaseStatementHandler { ...
- 阅读源码(IV)
往期系列: <由阅读源码想到> <由阅读源码想到 | 下篇> <阅读源码(III)> Eric S.Raymond的写于2014年的<How to learn ...
- 用nodejs实现简单爬虫
前言 本喵最近工作中需要使用node,并也想晋升为全栈工程师,所以开始了node学习之旅,在学习过程中, 我会总结一些实用的例子,做成博文和视频教程,以实例形式来理解体会node的用法,所以跟小猫 ...
- Unity使用C++作为游戏逻辑脚本的研究(二)
文章申明:本文来自JacksonDunstan的博客系列文章内容摘取和翻译,版权归其所有,附上原文的链接,大家可以有空阅读原文:C++ Scripting( in Unity) 上一篇文章写完,有同学 ...
- 使用 focus() 和 blur()
<html> <head> <style type="text/css"> a:active {color:green} </style& ...
- TensorFlow学习记录(一)
windows下的安装: 首先访问https://storage.googleapis.com/tensorflow/ 找到对应操作系统下,对应python版本,对应python位数的whl,下载. ...
- JSPWiki安装配置及FCKEditor的集成
版本:JSPWiki-2.8.2 FCKeditor_2.6.3 安装方法我参照:http://doc.jspwiki.org/2.4/wiki/InstallingJSPWiki FCKEd ...
- LR性能测试结果样例分析
http://www.cnblogs.com/hyzhou/archive/2011/11/16/2251316.html 测试结果分析 LoadRunner性能测试结果分析是个复杂的过程,通常可 ...