前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >腾讯云V3签名方法之iOS

腾讯云V3签名方法之iOS

原创
作者头像
许岳操
发布2020-08-03 17:17:28
3.3K0
发布2020-08-03 17:17:28
举报
文章被收录于专栏:技术拓展

签名方法 v3

签名方法 v3 (TC3-HMAC-SHA256)功能上覆盖了以前的签名方法 v1,而且更安全,支持更大的请求,支持 json 格式,性能有一定提升,推荐使用该签名方法计算签名。

首次接触,建议使用 API Explorer 中的“签名串生成”功能,选择签名版本为“API 3.0 签名 v3”,可以生成签名过程进行验证,也可直接生成 SDK 代码。推荐使用腾讯云 API 配套的 7 种常见的编程语言 SDK,已经封装了签名和请求过程,均已开源,支持 PythonJavaPHPGoNodeJS.NETC++

腾讯云 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,以及时间戳等信息均与上述文档中保持一致

计算签名的方法:

代码语言:javascript
复制
// 计算签名
-(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-8\nhost:" 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

文档中的结果一致,说明签名准确无误

计算签名方法中调用到的其他方法如下:

代码语言:javascript
复制
//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] = {'\0','\0','\0'};
    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

这篇文章对您有帮助的话,记得给小编点个赞 !

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 签名方法 v3
    • 计算签名的方法:
      • 各步骤结果验证:
      • 这篇文章对您有帮助的话,记得给小编点个赞 !
      相关产品与服务
      文字识别
      文字识别(Optical Character Recognition,OCR)基于腾讯优图实验室的深度学习技术,将图片上的文字内容,智能识别成为可编辑的文本。OCR 支持身份证、名片等卡证类和票据类的印刷体识别,也支持运单等手写体识别,支持提供定制化服务,可以有效地代替人工录入信息。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档