想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。
之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。
可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多,没有那么多模棱两可的参数,也可能是我的错觉。当前现在腾讯云有了各种语言的代码示例,直接抄即可。
https://cloud.tencent.com/document/api/551/30636
踩过的坑
- 在写header的时候,将Action等头部名直接写入,实际上,需要在前面加上 “X-TC-”。
- 根据文档步骤1 拼接规范请求串 时,漏掉空行
POST
/
content-type:application/json; charset=utf-8
host:cvm.tencentcloudapi.com
x-tc-action:describeinstances
content-type;host;x-tc-action
35e9c5b0e3ae67532d3c9f17ead6c90222632e5b1ff7f6e89887f1398934f064
上面代码中有两个空行,不可忽略。
3. 步骤2中,获取当前日期,需要 与UTC 标准时间日期一致。
4. 步骤3中,计算签名 文档示例与作者使用语言(PHP)的加密函数不同,把data和key颠倒了。
代码
function sign($data , $headers)
{
$this->date = gmdate("Y-m-d" , TIMESTAMP);
if(is_array($data)){
$data = json_encode($data);
}
$canonicalHeaders = '';
$signedHeaders = '';
foreach ($headers as $k => $v){
$canonicalHeaders .= $k . ":" . $v . "\n";
$signedHeaders .= $k . ";";
}
$canonicalHeaders = strtolower($canonicalHeaders);
$signedHeaders = strtolower(rtrim($signedHeaders , ";"));
$hashedRequestPayload = hash("SHA256" , $data);
// 1
$canonicalRequest = "POST\n" . //请求方法
"/\n" . //URI 参数,API 3.0 固定为正斜杠(/)
"\n" . //URL 中的查询字符串
"$canonicalHeaders\n" . //参与签名的头部信息
"$signedHeaders\n" . //哪些头部参与了签名
"$hashedRequestPayload";; // 请求正文做 SHA256 哈希
echo $canonicalRequest;
echo "<hr>";
$hashCanonicalRequest = strtolower(bin2hex(hash('sha256' , $canonicalRequest , true)));
// 2
$CredentialScope = "{$this->date}/tmt/tc3_request";
$secretSigning = [
'TC3-HMAC-SHA256' , //签名算法
$this->time , //请求时间戳
$CredentialScope , //凭证范围,格式为 Date/service/tc3_request
$hashCanonicalRequest , //步骤1拼接所得的字符串
];
$secretSigning = implode("\n" , $secretSigning);
echo $secretSigning;
echo "<hr>";
//3 计算签名
$secretDate = hash_hmac('sha256' , $this->date , "TC3$this->SecretKey" , true);
$SecretService = hash_hmac('sha256' , "tmt" , $secretDate , true);
$SecretSigning = hash_hmac('sha256' , "tc3_request" , $SecretService , true);
$Signature = bin2hex(hash_hmac('sha256' , $secretSigning , $SecretSigning , true)); // 返回十六进制字符串
echo $Signature;
echo "<hr>";
//4 拼接 Authorization
$Authorization = "TC3-HMAC-SHA256 ".
"Credential={$this->SecretId}/$CredentialScope, ".
"SignedHeaders=$signedHeaders, ".
"Signature=$Signature";
echo $Authorization . PHP_EOL;
echo "<hr>";
return $Authorization;
}