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对象存储做第三方存储云服务,把一些文件都放在上面,这里主要有三中实现方式:第一种就是在控制台去设置好,直接上传文件.第二种就是走服务端,上传文件,就是说,上传文件是从服务端去上传上去 ...
随机推荐
- 《java入门第一季》二维数组三个案例详解
案例一:遍历二维数组 /* 需求:二维数组遍历 外循环控制的是二维数组的长度,其实就是一维数组的个数行数. 内循环控制的是一维数组的长度,每一行,一维数组元素分别的个数. */ class Array ...
- DBUtils源码分析
其实,在这篇文章里,我只是分析了dbutis的query的运作流程. 至于类为什么要这样设计,蕴含的设计模式等等高级知识点咱们在下节再探讨. 先看看最简单的DBUtils是如何工作的. 数据库里有一张 ...
- hadoop 数据倾斜
数据倾斜是指,map /reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,这是因为某一个key的条数比其他key多很多(有 ...
- ubuntu12.04:Tomcat 7服务器:手动安装
1.下载tomcat7.0.34. 网址:http://tomcat.apache.org/ 2.下载的文件解压在下载: 进入目录: cd /usr/local 创建目录 : sudo mkdir d ...
- [ Java学习基础 ] Java的对象容器 -- 集合
当你有很多书时,你会考虑买一个书柜,将你的书分门别类摆放进入.使用了书柜不仅仅使房间变得整洁,也便于以后使用书时方便查找.在计算机中管理对象亦是如此,当获得多个对象后,也需要一个容器将它们管理起来,这 ...
- LeetCode - 验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树. 一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右子树自身必须也是二叉搜索树. ...
- day09_request&response学习笔记
============================================================ 一.HttpServletResponse接口 p.MsoNormal { m ...
- 02_Linux学习_命令
帮助命令: xxx --help man xxx 列出当前目录下的目录和文件: ls ls -l ls --help ...
- javap
本词条缺少概述.信息栏.名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! javap是jdk自带的一个工具,可以反编译,也可以查看java编译器生成的字节码,是分析代码的一个好工具. j ...
- Nginx日志配置及配置调试
防火墙内的内网服务器,因为网关传过来的remot_addr都一样,不得不对Nginx的日志格式做了配置 配置语法如下: log_format myformat '$http_x_forwarded ...