腾讯云V3签名方法之iOS
签名方法 v3
签名方法 v3 (TC3-HMAC-SHA256)功能上覆盖了以前的签名方法 v1,而且更安全,支持更大的请求,支持 json 格式,性能有一定提升,推荐使用该签名方法计算签名。
首次接触,建议使用 API Explorer 中的“签名串生成”功能,选择签名版本为“API 3.0 签名 v3”,可以生成签名过程进行验证,也可直接生成 SDK 代码。推荐使用腾讯云 API 配套的 7 种常见的编程语言 SDK,已经封装了签名和请求过程,均已开源,支持 Python、Java、PHP、Go、NodeJS、.NET、C++。
腾讯云 API 会对每个请求进行身份验证,用户需要使用安全凭证,经过特定的步骤对请求进行签名(Signature),每个请求都需要在公共请求参数中指定该签名结果并以指定的方式和格式发送请求。
目前提供7 种常见的编程语言SDK,封装了签名和请求过程,均已开源
有一些需求移动端直接请求接口,这时候就需要我们自己写签名了,安卓可以直接复制JAVA代码,iOS方面官方文档目前没有OC示例,也没有Swift示例
Swift示例见:https://cloud.tencent.com/developer/article/1602241
接下来我们按照腾讯云文档中的一个签名过程来实现OC的签名
https://cloud.tencent.com/document/product/866/33519
为了清晰展示签名的准确性,用户的 SecretId 和 SecretKey,以及时间戳等信息均与上述文档中保持一致
计算签名的方法:
// 计算签名
-(NSDictionary *)calculationSignature{
NSString *SECRET_ID = @"AKIDz8krbsJ5yKBZQpn74WFkmLPx3EXAMPLE";
NSString *SECRET_KEY = @"Gu5t9xGARNpq86cd98joQYCN3EXAMPLE";
NSString *CType = @"application/json; charset=utf-8";
NSString *service = @"cvm";
NSString *host = @"cvm.tencentcloudapi.com";
NSString *hostn = [host stringByAppendingString:@"n"];
NSString *region = @"ap-guangzhou";
NSString *action = @"DescribeInstances";
NSString *version = @"2017-03-12";
NSString *algorithm = @"TC3-HMAC-SHA256";
NSString *timestamp = @"1551113065"; //此处用官方文档中的时间戳
NSString *date = [self getUTCStr];
// ************* 步骤 1:拼接规范请求串 *************
NSString *httpRequestMethod = @"POST";
NSString *canonicalUri = @"/";
NSString *canonicalQueryString = @"";
NSString *canonicalHeaders = [@"content-type:application/json; charset=utf-8nhost:" stringByAppendingString:hostn];
NSString *signedHeaders = @"content-type;host";
NSString *bodyStr = @"{"Limit": 1, "Filters": [{"Values": ["\u672a\u547d\u540d"], "Name": "instance-name"}]}";
NSString *hashedRequestPayload = [self sha256HashFor:bodyStr];
NSString *canonicalRequest= [[NSString alloc] initWithFormat:@"%@%@%@%@%@%@%@%@%@%@%@", httpRequestMethod,@"n",canonicalUri,@"n", canonicalQueryString,@"n", canonicalHeaders,@"n", signedHeaders,@"n", hashedRequestPayload];
NSLog(@"第一步结果:%@%@",@"n",canonicalRequest);
// ************* 步骤 2:拼接待签名字符串 *************
NSString *credentialScope = [[NSString alloc]initWithFormat: @"%@%@%@%@", date,@"/",service,@"/tc3_request"];
NSString *hashedCanonicalRequest = [self sha256HashFor:canonicalRequest];
NSString *stringToSign = [[NSString alloc] initWithFormat:@"%@%@%@%@%@%@%@", algorithm,@"n",timestamp,@"n",credentialScope,@"n",hashedCanonicalRequest];
NSLog(@"第二步结果:%@%@",@"n",stringToSign);
// ************* 步骤 3:计算签名 *************
NSString * key1 = [self hexStringFromString:[@"TC3" stringByAppendingString:SECRET_KEY]];
NSString *secretDate = [self hmacForHexKey:key1 andStringData:date];
// NSLog(@"secretDate:%@", secretDate);
NSString *secretService = [self hmacForHexKey:secretDate andStringData:service];
// NSLog(@"secretService:%@", secretService);
NSString *secretSigning = [self hmacForHexKey:secretService andStringData:@"tc3_request"];
// NSLog(@"secretSigning:%@", secretSigning);
NSString *signature = [self hmacForHexKey:secretSigning andStringData:stringToSign];
NSLog(@"第三步结果:%@%@",@"n",signature);
// ************* 步骤 4:拼接 Authorization *************
NSString *authorization = [[NSString alloc] initWithFormat: @"%@ Credential=%@/%@, SignedHeaders=%@, Signature=%@",algorithm,SECRET_ID,credentialScope, signedHeaders, signature];
NSLog(@"第四步结果:%@%@",@"n",authorization);
NSDictionary *dic = @{
@"URL": [@"https://" stringByAppendingString:host],
@"Authorization": authorization,
@"ContentType": CType,
@"Host": host,
@"X-TC-Action": action,
@"X-TC-Version": version,
@"X-TC-Timestamp": timestamp,
@"X-TC-Region": region,
};
NSLog(@"最终完整的调用信息:%@%@",@"n",dic);
return dic;
}
各步骤结果验证:
每一步结果都与https://cloud.tencent.com/document/product/866/33519
文档中的结果一致,说明签名准确无误
计算签名方法中调用到的其他方法如下:
//SHA256加密
-(NSString*)sha256HashFor:(NSString*)input{
const char* str = [input UTF8String];
unsigned char result[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(str, (CC_LONG)strlen(str), result);
NSMutableString *ret = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
for(int i = 0; i<CC_SHA256_DIGEST_LENGTH; i++)
{
[ret appendFormat:@"%02x",result[i]];
}
ret = (NSMutableString *)[ret uppercaseString];
return [ret lowercaseString];
}
// hmac256加密
- (NSString *)hmacForHexKey:(NSString *)hexkey andStringData:(NSString *)data
{
NSData *keyData = [self dataFromHexString:hexkey];
const char *cKey = [keyData bytes];
const char *cData = [data cStringUsingEncoding:NSUTF8StringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, keyData.length, cData, strlen(cData), cHMAC);
return [self convertDataToHexStr: [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)]];
}
- (NSString *)convertDataToHexStr:(NSData *)data{
if (!data || [data length] == 0) {
return @"";
}
NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
[data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
unsigned char *dataBytes = (unsigned char*)bytes;
for (NSInteger i = 0; i < byteRange.length; i++) {
NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
if ([hexStr length] == 2) {
[string appendString:hexStr];
} else {
[string appendFormat:@"0%@", hexStr];
}
}
}];
return string;
}
// 获取UTC时间
-(NSString *)getUTCStr{
NSTimeInterval time = 1551113065;//此处使用腾讯云文档中的时间戳,实际请求时需要获取当前时间
NSDate *currentDate = [NSDate dateWithTimeIntervalSince1970:(NSTimeInterval)time];
//转为字符串
NSDateFormatter *format = [[NSDateFormatter alloc]init];
NSTimeZone* timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
[format setTimeZone:timeZone];
[format setDateFormat:@"yyyy-MM-dd"];
return [format stringFromDate:currentDate];
}
// string 转data
- (NSData *)dataFromHexString:(NSString *)sHex {
const char *chars = [sHex UTF8String];
int i = 0;
NSUInteger len = sHex.length;
NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[3] = {' ',' ',' '};
unsigned long wholeByte;
while (i < len) {
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:1];
}
return data;
}
// 普通转为16进制
- (NSString *)hexStringFromString:(NSString *)string{
NSData *myD = [string dataUsingEncoding:NSUTF8StringEncoding];
Byte *bytes = (Byte *)[myD bytes];
//下面是Byte 转换为16进制。
NSString *hexStr=@"";
for(int i=0;i<[myD length];i++)
{
NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16进制数
if([newHexStr length]==1)
hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];
else
hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr];
}
return hexStr;
}
参考
OC : https://github.com/williammyuan/tencentcloud-ios
Swift : https://cloud.tencent.com/developer/article/1602241
这篇文章对您有帮助的话,记得给小编点个赞 !
- # Hadoop离线数据分析平台实战——230项目数据存储结构设计Hadoop离线数据分析平台实战——230项目数据存储结构设计
- ECJTUACM16 Winter vacation training #5 题解&源码
- Codeforces 716A Crazy Computer
- Hadoop数据分析平台实战——240JavaSDK数据收集引擎编写离线数据分析平台实战——240JavaSDK数据收集引擎编写
- Hadoop离线数据分析平台实战——290活跃用户分析Hadoop离线数据分析平台实战——290活跃用户分析
- Codeforces 719B Anatoly and Cockroaches
- 【一起学Python】爬取前程无忧招聘信息并写入Excel
- 【一起学Python】爬取网易云歌词
- Hadoop离线数据分析平台实战——370外链信息分析Hadoop离线数据分析平台实战——370外链信息分析
- POJ 1067 取石子游戏
- 【一起学Python】STEAM游戏评测爬虫
- Open Judge 2750 鸡兔同笼
- POJ 1017 Packets
- Hadoop离线数据分析平台实战——380MapReduce程序优化Hadoop离线数据分析平台实战——380MapReduce程序优化
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- codeforce 270B Multithreading
- flex-wrap align-content详解
- Code force-CodeCraft-20 (Div. 2) D. Nash Matrix 详解(DFS构造)
- HDU Problem D [ Humble number ]——基础DP丑数序列
- Java开发编程规范: 3.代码格式
- flex-direction
- css中清除浮动方式五
- css中-清除浮动方式四
- forin forof forEach myForEach
- 深拷贝,你懂吗?
- Codeforce-CodeCraft-20 (Div. 2)-C. Primitive Primes(本原多项式+数学推导)
- DOM事件机制(原理级别的)
- 杭电60题--part 1 HDU1003 Max Sum(DP 动态规划)
- js的的的图片随屏幕滚动而滑入滑出的效果(万 万。。。字长文)
- Codeforce-CodeCraft-20 (Div. 2)-B. String Modification (找规律+模拟)