[技术博客]阿里云签名机制字符串的C语言实现
[技术博客]阿里云签名机制字符串的C语言实现
问题描述见:阿里云签名机制
话不多说,上字符串函数转化函数代码
bool AlicloudRequest::sendV2Request() {
if( query_parameters.find( "Action" ) == query_parameters.end() ) {
this->errorCode = "E_INTERNAL";
this->errorMessage = "No action specified in request.";
dprintf( D_ALWAYS, "No action specified in request, failing.\n" );
return false;
}
std::string protocol, host, httpRequestURI;
if(! parseURL( serviceURL, protocol, host, httpRequestURI )) {
this->errorCode = "E_INVALID_SERVICE_URL";
this->errorMessage = "Failed to parse service URL.";
dprintf( D_ALWAYS, "Failed to match regex against service URL '%s'.\n", serviceURL.c_str() );
return false;
}
if( (protocol != "http" && protocol != "https" && protocol != "x509" && protocol != "euca3" && protocol != "euca3s" ) ) {
this->errorCode = "E_INVALID_SERVICE_URL";
this->errorMessage = "Service URL not of a known protocol (http[s]|x509|euca3[s]).";
dprintf( D_ALWAYS, "Service URL '%s' not of a known protocol (http[s]|x509|euca3[s]).\n", serviceURL.c_str() );
return false;
}
std::string hostAndPath = host + httpRequestURI;
std::transform( host.begin(), host.end(), host.begin(), & tolower );
if( httpRequestURI.empty() ) { httpRequestURI = "/"; }
if( protocol == "euca3" || protocol == "euca3s" ) {
query_parameters.erase( "InstanceInitiatedShutdownBehavior" );
}
std::string keyID;
if( protocol != "x509" ) {
if( ! readShortFile( this->accessKeyFile, keyID ) ) {
this->errorCode = "E_FILE_IO";
this->errorMessage = "Unable to read from accesskey file '" + this->accessKeyFile + "'.";
dprintf( D_ALWAYS, "Unable to read accesskey file '%s', failing.\n", this->accessKeyFile.c_str() );
return false;
}
trim( keyID );
query_parameters.insert( std::make_pair( "AccessKeyId", keyID ) );
}
std::stringstream ss;
ss<<rand();
std::string randnum = ss.str();
query_parameters.insert( std::make_pair( "SignatureMethod", "HMAC-SHA1" ) );
query_parameters.insert( std::make_pair( "SignatureNonce", randnum ) );
query_parameters.insert( std::make_pair( "SignatureVersion", "1.0" ) );
Throttle::now( & signatureTime );
time_t now; time( & now );
//now+=28800;
struct tm brokenDownTime; gmtime_r( & now, & brokenDownTime );
char iso8601[32];
strftime(iso8601, sizeof(iso8601), "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
query_parameters.insert( std::make_pair( "Timestamp", iso8601 ) );
std::string stringToSign = "POST&%2F&"
//+ host + "\n"
//+ httpRequestURI + "\n"
+ alicloudURLEncode(canonicalQueryString);
std::string saKey;
if( protocol == "x509" ) {
saKey = std::string( "not-the-DN" );
dprintf( D_FULLDEBUG, "Using '%s' as secret key for x.509\n", saKey.c_str() );
} else {
if( ! readShortFile( this->secretKeyFile, saKey ) ) {
this->errorCode = "E_FILE_IO";
this->errorMessage = "Unable to read from secretkey file '" + this->secretKeyFile + "'.";
dprintf( D_ALWAYS, "Unable to read secretkey file '%s', failing.\n", this->secretKeyFile.c_str() );
return false;
}
trim( saKey );
}
unsigned int mdLength = 0;
unsigned char messageDigest[EVP_MAX_MD_SIZE];
const unsigned char * hmac = HMAC( EVP_sha1(), saKey.c_str(), saKey.length(),
(const unsigned char *)stringToSign.c_str(), stringToSign.length(), messageDigest, & mdLength );
if( hmac == NULL ) {
this->errorCode = "E_INTERNAL";
this->errorMessage = "Unable to calculate query signature (SHA1 HMAC).";
dprintf( D_ALWAYS, "Unable to calculate SHA1 HMAC to sign query, failing.\n" );
return false;
}
char * base64Encoded = condor_base64_encode( messageDigest, mdLength );
std::string signatureInBase64 = base64Encoded;
free( base64Encoded );
std::string postURI;
if( protocol == "x509" ) {
postURI = "https://" + hostAndPath;
} else if( protocol == "euca3" ) {
postURI = "http://" + hostAndPath;
} else if( protocol == "euca3s" ) {
postURI = "https://" + hostAndPath;
} else {
postURI = this->serviceURL;
}
dprintf( D_FULLDEBUG, "Request URI is '%s'\n", postURI.c_str() );
size_t index = canonicalQueryString.find( "AccessKeyId=" );
if( index != std::string::npos ) {
size_t skipLast = canonicalQueryString.find( "&", index + 14 );
char swap = canonicalQueryString[ index + 15 ];
canonicalQueryString[ index + 15 ] = '\0';
char const * cqs = canonicalQueryString.c_str();
if( skipLast == std::string::npos ) {
dprintf( D_FULLDEBUG, "Post body is '%s...'\n", cqs );
} else {
dprintf( D_FULLDEBUG, "Post body is '%s...%s'\n", cqs, cqs + skipLast );
}
canonicalQueryString[ index + 15 ] = swap;
} else {
dprintf( D_FULLDEBUG, "Post body is '%s'\n", canonicalQueryString.c_str() );
}
return sendPreparedRequest( protocol, postURI, canonicalQueryString );
}
[技术博客]阿里云签名机制字符串的C语言实现的更多相关文章
- [技术博客] 用户验证码验证机制---redis缓存数据库的使用
目录 问题引入 初识redis 实际应用 作者:马振亚 问题引入 在这次的开发过程中,我们的需求中有一个是普通用户可以通过特定的机制申请成为社长.因为只有部分人才能验证成功,所以这个最开始想了两种思路 ...
- 【技术博客】JWT的认证机制Django项目中应用
开发组在开发过程中,都不可避免地遇到了一些困难或问题,但都最终想出办法克服了.我们认为这样的经验是有必要记录下来的,因此就有了[技术博客]. JWT的认证机制Django项目中应用 这篇技术博客基于软 ...
- [转]有哪些值得关注的技术博客(Java篇)
有哪些值得关注的技术博客(Java篇) 大部分程序员在自学的道路上不知道走了多少坑,这个视频那个网站搞得自己晕头转向.对我个人来说我平常在学习的过程中喜欢看一些教程式的博客.这些博客的特点: 1. ...
- 最值得收藏的java技术博客(Java篇)
第一个:java_my_life 作者介绍:找不到原作者信息.大概做了翻阅全部是2012年的博客. 博客主要内容:主要内容是关于Java设计模式的一些讲解和学习笔记,在相信对学习设计模式的同学帮助很大 ...
- 技术人如何利用 github+Jekyll ,搭建一个独立免费的技术博客
上次有人留言说,技术博客是程序员的标配,但据我所知绝大部分技术同学到现在仍然没有自己的技术博客.原因有很多,有的是懒的写,有的是怕写不好,还有的是一直想憋个大招,幻想做到完美再发出来,结果一直胎死腹中 ...
- IT公司技术博客地址
IT公司技术博客 美团点评技术团队今日头条技术博客Tencent ISUX DesignTGideas-腾讯互动娱乐创意设计团队>AlloyTeam | 腾讯全端 AlloyTeam 团队 Bl ...
- 不可思议的hexo,五分钟教你免费搭一个高逼格技术博客
引言 作为程序员拥有一个属于自己的个人技术博客,绝对是百利无一害的事,不仅方便出门装b,面试时亮出博客地址也会让面试官对你的好感度倍增.经常能在很多大佬的技术文章的文末,看到这样一句话: " ...
- 技术博客——微信小程序的架构与原理
技术博客--微信小程序的架构与原理 在两个月的微信小程序开发过程中,我曾走了不少弯路,也曾被很多现在看来十分可笑的问题所困扰.这些弯路与困扰,基本上都是由于当时对小程序的架构理解不够充分,对小程序的原 ...
- [技术博客] 敏捷软工——JavaScript踩坑记
[技术博客] 敏捷软工--JavaScript踩坑记 一.一个令人影响深刻的坑 1.脚本语言的面向对象 面向对象特性是现代编程语言的基本特性,JavaScript中当然集成了面向对象特性.但是Java ...
随机推荐
- 信安周报-第04周:系统函数与UDF
信安之路 第04周 前言 这周自主研究的任务如下: 附录解释: SQLi的时候应对各种限制,可以使用数据库自带的系统函数来进行一系列变换绕过验证 eg:字符串转换函数.截取字符串长度函数等 注入的时候 ...
- 七雄Q传封包辅助技术探讨回忆贴
前言 网页游戏2013年左右最火的类型最烧钱游戏,当年的我也掉坑了.为了边玩还满足码农精神我奋力的学习如何来做外挂.2013年我工作的第二个年头.多一半…介绍下游戏<七雄Q传>是北京游戏谷 ...
- 排序算法Java代码实现(四)—— 归并排序
本篇内容: 归并排序 归并排序 算法思想: 将两个或两个以上的有序表合并成一个新的有序表, 即把待排序序列分成若干个子序列,每个子序列是有序的,然后在把有序子序列合并为整体有序序列. 此算法分为两步: ...
- 15、VUEX-Store
1.什么是VUEX Vuex是管理vue的组件状态的工具. 个人理解:vuex是管理组件之间通信的一个插件. 2.为什么要用VUEX 我们知道组件之间是独立的,组件之间想要实现通信,我目前知道的就只有 ...
- SQL Server merge用法
有两个表名:source 表和 target 表,并且要根据 source 表中匹配的值更新 target 表. 有三种情况: source 表有一些 target 表不存在的行.在这种情况下,需要将 ...
- 24个Jvm面试题总结及答案
1.什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? Java虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Java虚拟机执行的字节码文件. Java被 ...
- 如何简单使用tensorboard展示(一)
我使用tensorboard中的graph做了展示,至于其它功能可以类推,其代码如下: import numpy as npimport tensorflow as tf x_img = np.arr ...
- 何为KVM克隆和快照
KVM的克隆.快照都是老生常谈的问题,资料也非常多,这里只是针对个人实验的记录,方便以后查阅. 虚拟机克隆 虚拟机的克隆操作是再频繁不过了,安装好第一台虚拟机后就可以进行基础设置,已此虚拟机为模板,以 ...
- Vue.js项目实战-打造线上商城
首先上一下完成后的效果: 首页: 商品详情页: 购物车页(其实还有个订单页,只是和购物车页基本类似,所以就不截图啦): 开始项目: 由于涉及的是前后端分离,所以我们的后台数据就模拟存储于浏览器端(co ...
- 关于Git的用法
关于Git Git 是一个分布式版本控制软件,与CVS.Subversion一类的集中式版本控制工具不同,它采用了分布式版本库的作法,不需要服务器端软件,就可以运作版本控制,使得源代码的发布和交流极其 ...