手机版

PHP生成腾讯云COS接口所需的请求签名

时间:2021-08-31 来源:互联网 编辑:宝哥软件园 浏览:137

什么是COS和请求签名

COS是腾讯云对象存储的简称和简称。请求签名是第三方调用COS相关接口时,由特定算法创建的一组字符串信息。它将唯一识别当前第三方身份,并为双方提供通信。只有有效的签名COS才会提供服务。

目标

使用PHP创建COS接口所需的请求签名,并与官方文档中给出的例子进行比较,验证算法的正确性

理解请求签名

我们先来看一份正式文件要求签字的样子

q-sign-algorithm=sha1q-AK=[secrettid]q-sign-time=[sign time]q-key-time=[key time]q-header-list=[signedheader list]q-URL-param-list=[signed parameter list]q-Signature=[Signature]

请求签名的特征摘要

它是一种键值对格式,有一串key=value,有7对key=value sha1也是参数,但是截止到官方发布,只支持sha1,所以可以直接赋值三个值,SignedHeaderList、SignedParameterList和Signature。算法生成键值对的具体描述请参考官方文件。

逐个击破

总共需要7个值用于签名请求,这将在下面逐一解释。

q-sign-algorithm

签名算法,官方目前只支持sha1,所以直接给出值就可以了

q-ak

账号ID,也就是用户的SecretId,可以从控制台云API密钥页面获取

q-sign-time

当前签名的有效起止时间,Unix时间戳格式,英文分号;分段,格式如1480932292;1481012298

q-key-time

具有与q符号时间相同的值

q-header-list

人们理解它是由HTTP请求头组成,取全部或部分请求头,以key:value的形式取出请求项的关键部分,转换成小写,根据字典对多个键进行排序,使用字符;连接,最后形成一个字符串

例如,有两个原始请求头:

host : bucket 1-1254000000 . cos . AP-Beijing . myqcloud.com content-type : image/JPEG

关键是主机和内容类型,操作后输出内容类型;宿主

从010到1010,人们理解它是由HTTP请求参数组成的。取全部或部分请求参数,以key=value的形式取出请求参数的关键部分,并转换成小写。多个关键字按字典和字符排序;连接,最后形成一个字符串

如果原始的HTTP请求是:

GET /?前缀=abcmax-key=20

Key是前缀和max-key,max-key是操作后输出;前缀,如果请求没有参数,如put和post,这是空的

q-url-param-list

根据HTTP内容计算签名,算法由COS提供,只需要按要求给出值即可

q-signature

在开始写逻辑之前,先看看官方给出的参考值和计算结果,以便与自己开发的逻辑进行比较

HTTP原始请求也可以理解为签名计算前或不需要签名时的HTTP请求:

PUT/test file 2 HTTP/1.1host : bucket 1-1254000000 . cos . AP-Beijing . myqcloud.comx-cos-content-sha 1: 7 b 502 c 3a 1 f 48 c 8609 AE 212 cdff 639 dee 39673 f5ex-cos-storage-class :标准

你好世界

计算签名后应获得的HTTP请求:

PUT/test file 2 HTTP/1.1host : bucket 1-1254000000 . cos . AP-Beijing . myqcloud.comx-cos-content-sha 1: 7 b 502 c 3a 1 f 48 c 8609 AE 212 cdff 639 de 39673 F5 ex-cos-storage-class : sta ndardauthorizations : q-sign-algorithm=sha1q-AK=akidqjzz1417853898 q-key-time=1417773892;1417853898 q-header-list=host;x-cos-含量-sha1;x-cos-storage-class q-URL-param-list=q-signature=14e 6 EBD 7955 B0 c6da 532151 BF 97045 e2c 5a 64 e 10

你好世界

结论:如果授权后能得到字符串,算法是正确的

官方示例及参照结果

我们来看看(官方提供的)用户信息和HTTP信息:

secretid:akidqjz 3 ltompvjbni5 litkwhlpfpwkn 9u 5q secretkey:bqyim75p 8x 0 iwvfsigqekwfprprshvhlz签名有效起始时间:1417773892 签名有效停止时间:1417853898 HTTP原始请求头:根据上一节示例不难得到超文本传送协议原始请求有三项内容主机、x-cos-内容-sha1和x-cos-存储类超文本传送协议请求参数:是放请求,没有?参数

准备工作

将准备工作中的各项参数带入请求签名规则,不难就可以得到结果,如下表:

键(键)值(值)备注q符号算法sha1目前仅支持sha1签名算法q-AK akidqjz 3 ltompvjbni5 litkwhlpfpwkn 9u 5q secret tid字段q-符号-时间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主机;x-cos-含量-sha1;x-cos-存储类超文本传送协议头部键的字典顺序排序列表参数列表参数列表为空q-signature 14e 6 EBD 7955 B0 c6da 532151 BF 97045 e2c 5a 64 e 10通过代码计算所得但q签名怎么来的?

刚才说到,q-签名也需要特定算法计算得来,下面就说明如何计算

计算请求签名

先看代码:

/** * 计算签名*机密、机密为必需参数,qSignStart,qSignEnd为调试需要,测试通过后应取消,改为方法内自动创建*/function get _ authorization($ secret tid,$secretKey,$qSignStart,$qSignEnd,$fileUri,$headers ){ /* *计算装货付款(货到付款)签名* 2018-05-17 *作者: cinlap[电子邮件受保护]* ref:https://cloud.tencent.com/document/product/436/7778 */$ qSignTime=' $ qSignStart;$ qSignEnd ';//UNIX _时间戳;UNIX _ timestamp $ qkey time=$ qSignTime;$ header _ list=get _ q _ header _ list($ headers);//如果上呼吸道感染中带有?的请求参数,该处应为数组排序后的字符串组合$ url _ param _ list=//计算签名$ HttpMethod=' put $ HttPuri=$ Fileuri//与问-网址-参数-列表相同$ HttpParameters=$ URL _ param _ list;//将自定义请求头分解为连接的字符串$ header string=get _ http _ header _ string($ header);//计算签名中的签名部分$ signTime=$ qSignTime $ sign key=hash _ hmac(' sha1 ',$ sign time,$ secretKey);$ HttpString=' $ HttpMethod \ n $ Httpuri \ n $ Httpparameters \ n $标头字符串\ n ';$ sha1 edhttpsting=sha1($ httpsting);$ StrIngtosign=' sha1 \ n $签名时间\ n $ sha1 edhttpstring \ n ';$signature=hash_hmac('sha1 ',$stringToSign,$ SignKey);//组合结果$ authorization=' q-sign-algorithm=sha1q-AK=$ secretidq-sign-time=$ qSignTimeq-key-time=$ qketimeq-header-list=$ header _ listq-URL-param-list=$ URL _ param _ listq-signature=$ signature ';返回$授权;}为了测试,该方法参数应该是多过需要了,前六个参数是已经给出的,是来自用户的,因此直接赋值即可得到下边字符串:

$ authorization=' q-sign-algorithm=sha1q-AK=$ secretidq-sign-time=$ qSignTimeq-key-time=$ qkey time.

$header_list这个值要符合q-标题-列表规则因此需要计算,逻辑是上文已经描述,是从既定的请求项中抽出键组成有序字符串,代码如下:

/** * 按装货付款(货到付款)要求对标题列表内容进行转换* 提取所有密钥*字典排序*密钥转换为小写* 多对键=值之间用连接符连接* */函数get_q_header_list($headers){ if(!is _ array($ headers)){ return false;}请尝试{ $ TMParray=array();foreach($ header as $ key=$ value){ array _ push($ tmpArray,strtolow($ key));} sort($ TMParray);返回内爆(';',$ TMParray);} catch(Exception $ error){ return false;} } $ URL-参数-列表上面讲过,这个值是超文本传送协议请求参数,对于放方法没有?参数,自然值为空,所以代码中"偷懒"直接给了空字符串。

签名的计算和需要小心的地方

官方给出了完整的算法,PHP甚至还写了代码,应该很开心(但是!因为看公文的头晕眼花或者踩坑,那就一起解释吧),先看签名的“格式”:

sign key=HMAC-SHA1(secrettkey,'[q-key-time]')httpsting=[HttpMethod]\ n[httppuri]\ n[HttpParameters]\ n[httpaders]\ n sign sign=[q-sign-算法]\ n[q-sign-time]\ nsha 1-HASH(httpsting)\ n sign key=HMAC-SHA1(sign key,StringToSign)

我们来看看Signature的完整算法:

$ signTime=$ qSignTime$signKey=hash_hmac('sha1 ',$signTime,$ secretKey);$ httpString=' $ HttpMethod \ n $ Httpuri \ n $ Httpparameters \ n $ header string \ n ';$ sha1 edhttpsting=sha1($ httpsting);$ StrIngtosign=' sha1 \ n $ sign time \ n $ sha1 edhttpstring \ n ';$signature=hash_hmac('sha1 ',$stringToSign,$ SignKey);

$signTime:非常简单。由开始和结束时间组成的字符串可以通过$ signkey: hmac-sha1算法直接计算。$httpString:这四个部分需要单独描述。1.$ httpmethod: http request方法,小写,如put,get2,$ HttpURi:http request的URI部分。从“/”的虚拟根目录开始,例如/testfile表示在桶根目录下创建一个叫testfile的文件,/image/face1.jpg表示在根目录/image目录下创建一个叫face1.jpg的文件,不管是不是图片文件,不管3。$httpParameters:这是首先要小心的地方。它由HTTP原始请求参数组成,也就是在请求URI?在后面的部分,这个例子调用PUT Object接口,所以它是空的。如果不为空,则需要将请求参数的每一项的键值转换为小写,多对key=value按字典排序并相互连接。4.$headerString:这是第二个需要小心的地方,它由HTTP原始请求头组成。根据请求头,选择全部或部分请求头,并将每个项目的键转换为小写。对所有值进行URLEncode转换,将每种格式改为key=value,然后根据key对字典进行排序,最后通过连接器组合成字符串。这是我的逻辑,代码如下:

/* * *根据COS要求从数组中获取[HttpString]Signature中的内容*标准格式键=值键=值.*数组元素按键字典排序* *键转换为小写*值转换为UrlEncode *转换为键=值格式*键=值的对由连接器连接* */函数get _ http _ header _ string($ headers){ if(!is _ array($ headers)){ return false;}请尝试{ $ TMParray=array();foreach($ header as $ key=$ value){ $ tmpKey=strtolow($ key);$ TMParray[$ TMpkey]=urlencode($ value);} k sort($ TMParray);$ HeadRaray=array();foreach($ tmpArray as $ key=$ value){ array _ push($ header rarray,' $ key=$ value ');} return inquide(',$ header rarray);} catch(Exception $ error){ return false;}}为什么要小心?

HTTP原始请求头和请求参数用在四个地方,即请求签名中的q-header-list和签名中的HttpHeaders——。请求签名中的q-url-param-list和签名中的HttpParameters——都使用了HTTP请求参数。确保HTTP请求头和请求参数的数量与对象的数量一致

相同:用于生成q-header-list的HTTP请求头的数量和成员应该与用于生成HttpHeaders的数量和成员相同。q-url-param-list生成的HTTP请求参数的数量和成员与HttpParameters生成的相同:q-header-list和q-url-param-list只取关键部分,HttpHeaders和HttpParameters取关键部分和值部分输出结果并检查

此时,请求签名中有七个值,其中一些来自用户信息,一些需要计算。以上给出了所有的计算方法和个人对为什么计算的理解。最后只需要按照官方要求输出即可。看,在PostMan中选择Post方法,选择表单-数据方法提交数据,在Body中给出所有用户参数(这个地方是为了测试算法是否和官方一致,所以几乎所有的值都是Post提交的,实际时间和Host都可以在算法中创建)

提交后,返回结果

单词很小,结果单独提取

{ ' Authorization ' : ' q-sign-algorithm=sha1q-AK=akidqjz3 ltompvjbni5litkwhlfpwkn 9u 5 QQ-sign-time=1417773892;1417853898 q-key-time=1417773892;1417853898 q-header-list=host;x-cos-含量-sha1;x-cos-storage-class q-URL-param-list=q-signature=14e 6 EBD 7955 B0 c6da 532151 BF 97045 e2c 5a 64 e 10 ',Host ' : ' Bucket 1-125400000 . cos . AP-Beijing . myqcloud.com ',' Content-Length ' : ' 12000 ' } Host和Content-Length是我定制的输出,主要看授权部分。它们与官方文件给出的结果完全一致,并说明了算法

吐槽与反思

版本0.2

昨天基于对腾讯云API的“愤慨”和对遗忘的恐惧,急于写下想法,写得很潦草,发现土考人的官方文件顺序不一样,今天重写了

版本0.1

C#之前对接口做了研究,但是没有用。最后,成功调用腾讯技术支持提供的AWS SDK真的很累。这一次,我们需要把PHP作为一个项目来使用,这是必须克服的。应该没那么难,但一定要讨论我们的智力和年龄。不过我还是想再吐槽一下官方的文件,好像很详细,顺序也不够一致。示例代码的细节,比如参数,不够统一,容易让新手产生前后不怎么匹配的误解,有些细节和逻辑不能马上集成。比如,当我再次研究接口时,我意识到了[SignHeaderList]和计算[Signature]之间的关系。

版权声明:PHP生成腾讯云COS接口所需的请求签名是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。