COS签名
腾讯云cos xml接口签名文档
代码
Auth.h
/// @brief 返回cos_xml接口的签名 /// 腾讯云签名文档:https://qcloud.com/document/product/436/7778 /// @param app_id 项目的app_id /// @param secret_id 签名秘钥id,可在控制台获得 /// @param secret_key 签名秘钥,可在控制台获得 /// @param expired_time 签名文档中q_key_time,q_sign_time有效时间 /// @param uri 签名秘钥id,可在控制台获得 /// @param bucket_name bucket名字,可在控制台获得 /// @param op HTTP操作GET、PUT /// @param user_params 用户参数 /// @param user_headers http头部 /// @return string 签名,可用于访问cos的xml接口 static std::string AppSignXml(uint64_t app_id,const std::string& secret_id,const std::string& secret_key,uint64_t expired_time,const std::string& uri,const std::string& bucket_name,const std::string& op,const std::map<string,string>& user_params,string>& user_headers);
Auth.cpp
// 腾讯云签名算法文档:https://qcloud.com/document/product/436/7778 std::string Auth::AppSignXml(uint64_t app_id,string>& _user_params,string>& _user_headers) { // 将params和headers的key都转成小写(方便字典序排序) string key,value; std::map<string,string> user_params; for(std::map<string,string>::const_iterator it = _user_params.begin(); it != _user_params.end(); ++it) { key = CodecUtil::ToLower(it->first); value = it->second; user_params[key] = value; } std::map<string,string> user_headers; for(std::map<string,string>::const_iterator it = _user_headers.begin(); it != _user_headers.end(); ++it) { key = CodecUtil::ToLower(it->first); value = it->second; user_headers[key] = value; } // step 1: calc Signkey char q_key_time[30]; //key有效时间 uint64_t time_s = time((time_t*)NULL); //time返回10位unix时间,单位s snprintf(q_key_time,30,#if __WORDSIZE == 64 "%lu;%lu",#else "%llu;%llu",#endif time_s,time_s + expired_time); string sign_key = CodecUtil::HmacSha1(q_key_time,secret_key); string sign_key_str = CodecUtil::HexToStr(sign_key); #ifdef SIGN_DEBUG std::cout<< "***********************************************" << std::endl; std::cout<< "**********q_key:" << q_key_time << std::endl; std::cout<< "**********sign_key_str:\n" << sign_key_str <<std::endl; #endif // step 2: get FormatString string format_str; // operation format_str += CodecUtil::ToLower(op); format_str += "\n"; // uri format_str += CodecUtil::UrlEncode(uri); format_str += "\n"; // user_params string params_key,params_value,param_str; for(std::map<string,string>::const_iterator it = user_params.begin(); it != user_params.end(); ) { params_key = it->first; params_value = it->second; param_str = CodecUtil::ToLower(CodecUtil::UrlComponentEncode(params_key)) + "=" + CodecUtil::UrlComponentEncode(params_value); format_str += param_str; ++it; if(it != user_params.end()) format_str += "&"; } format_str += "\n"; //user_headers string header_key,header_value,header_str; for(std::map<string,string>::const_iterator it = user_headers.begin(); it != user_headers.end(); ) { header_key = it->first; header_value = it->second; header_str = CodecUtil::ToLower(CodecUtil::UrlComponentEncode(header_key)) + "=" + CodecUtil::UrlComponentEncode(header_value); format_str += header_str; ++it; if(it != user_headers.end()) format_str += "&"; } format_str += "\n"; string sha1_format_str = CodecUtil::GetFileSha1(format_str.c_str(),format_str.length()); #ifdef SIGN_DEBUG std::cout<< "**********format_str:\n" << format_str <<std::endl; std::cout<< "**********sha1_format_str:\n" << sha1_format_str <<std::endl; #endif // step 3: get StringToSign char q_sign_time[30]; //sign有效时间(key有效时间一般大于或等于sign有效时间) strcpy(q_sign_time,q_key_time); string str2sign; str2sign += "sha1\n"; str2sign += q_sign_time; str2sign += "\n"; str2sign += sha1_format_str; str2sign += "\n"; #ifdef SIGN_DEBUG std::cout<< "**********str2sign:\n" << str2sign <<std::endl; #endif // step 4: calc signature string signature = CodecUtil::HmacSha1(str2sign,sign_key_str); string signature_str = CodecUtil::HexToStr(signature); // step5: get Authorization string auth; auth += "q-sign-algorithm=sha1"; auth += "&q-ak="; auth += secret_id; auth += "&q-sign-time="; auth += q_sign_time; auth += "&q-key-time="; auth += q_key_time; auth += "&q-header-list="; //需要检查的header_key,字典序排列 // auth += "host;range"; for(std::map<string,string>::const_iterator it = user_headers.begin(); it != user_headers.end(); ) { auth += CodecUtil::ToLower(it->first); ++it; if(it != user_headers.end()) auth += ";"; } auth += "&q-url-param-list="; //需要检查的param_key,字典序排列 for(std::map<string,string>::const_iterator it = user_params.begin(); it != user_params.end(); ) { auth += CodecUtil::ToLower(it->first); ++it; if(it != user_params.end()) auth += ";"; } auth += "&q-signature="; auth += signature_str; #ifdef SIGN_DEBUG std::cout<< "**********auth:\n" << auth <<std::endl<<std::endl; std::cout<< "***********************************************" << std::endl; #endif return auth; }
测试demo
请到腾讯云申请对象存储帐号,控制太获取参数填到对应位置,Make编译,curl命令运行。
int main(){ // 腾讯云示例: // SecretKey: AKIDZfbOA78asKUYBcXFrJD0a1ICvR98JM // SecretID: QmFzZTY0IGlzIGEgZ2VuZXJp // 测试使用的 Bucket 是在中国华北地区的 testbucket,建立在开发商 AppID 为 125000000 的账户下 // GET Object 示例: // 以下示例内容展示了一个 GET Object 操作的签名示例, // 地址是 http://testbucket-125000000.cn-north.myqcloud.com/testfile // 并通过 Range 参数请求该文件的前 4 个字节。 // GET 请求: // GET /testfile HTTP/1.1 // Host: testbucket-125000000.cn-north.myqcloud.com // Range: bytes=0-3 //重要的事情说三遍 //这些默认参数是腾讯云给的,但是key和id只是演示,并不能通过cos的验证。请填写自己申请的腾讯云帐号的参数 //这些默认参数是腾讯云给的,但是key和id只是演示,并不能通过cos的验证。请填写自己申请的腾讯云帐号的参数 //这些默认参数是腾讯云给的,但是key和id只是演示,并不能通过cos的验证。请填写自己申请的腾讯云帐号的参数 uint64_t app_id = 125000000;//填写自己的腾讯云appid string secret_key = "AKIDZfbOA78asKUYBcXFrJD0a1ICvR98JM"; //填写自己的SecretKey,cos控制台查看 string secret_id = "QmFzZTY0IGlzIGEgZ2VuZXJp"; //填写自己的Secretid,cos控制台查看 uint64_t expired_time = 10000; string bucket_name = "testbucket"; // bucket名称 string uri = "/testfile"; //cos上面bucket下面的object路径,以/开始 string op = "GET"; map<string,string> user_params; map<string,string> user_headers; //填写host:<bucket_name>-<app_id>.<region>.myqcloud.com user_headers["Host"]="testbucket-125000000.cn-north.myqcloud.com"; user_headers["Range"]="bytes=0-3"; string auth1 = qcloud_cos::Auth::AppSignXml(app_id,secret_id,secret_key,expired_time,uri,bucket_name,op,user_params,user_headers); cout << auth1 <<endl<<endl; cout<< "curl -v http://" + user_headers["Host"] + uri +" "\ "-H \"Accept:*/*\" -H \"Range:" + user_headers["Range"] + "\" -H \"User-Agent:curl/7.29.0\" "\ "-H \"Authorization:" << auth1 << "\"" <<endl; return 0; }