首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无效签名: oauth_signature

无效签名: oauth_signature
EN

Stack Overflow用户
提问于 2012-11-04 11:35:56
回答 1查看 3.8K关注 0票数 7

我试图生成oauth_signature来使用Fatsecret ,但是得到无效的签名错误为了尽可能准确地生成签名值,我尝试遵循所有提到的这里步骤(参见步骤2)。他们说:

使用RFC2104定义的HMAC-SHA1 1签名算法对请求进行签名,其中文本是签名基字符串,密钥是由“&”字符分隔的“消费者秘密”和“访问秘密”的连接值(显示&“”,即使访问秘密是空的,因为有些方法不需要访问令牌)。 计算出的摘要八进制字符串,首先每个RFC2045使用base64 64编码,然后使用RFC3986百分比编码(%xx)机制转义,即oauth_signature。

对于base64编码,我使用了QSStrings.h

我编写的步骤如下:

代码语言:javascript
复制
- (void)viewDidLoad
{
NSTimeInterval intervalFloat = [[NSDate date] timeIntervalSince1970];
int interval = (int) intervalFloat;
NSLog(@"time interval: %d",interval);

//for oauth_nonce random string
NSString *randomString = [self genRandString]; //see definition below
NSLog(@"%@",randomString);

NSString *requestString = [NSString stringWithFormat:@"POST&http%3A%2F%2Fplatform.fatsecret.com%2Frest%2Fserver.api&format%3Djson%26method%3Dprofile.create%26oauth_consumer_key%3Db753c99ccxxxxxx%26oauth_nonce%3D%@%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D%d%26oauth_version%3D1.0",randomString,interval];
NSString *secret = @"3959096c04xxxxxxxx&";

NSString *encodedStr = [self hmacsha1:requestString secret:secret]; //see definition below
NSLog(@"encodedStr: %@",encodedStr);

NSString *encodedString = [self urlEncodeValue:encodedStr]; //see definition below
NSLog(@"encodedString: %@",encodedString);

NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://platform.fatsecret.com/rest/server.api?format=json&method=profile.create&oauth_consumer_key=b753c99ccxxxxxx&oauth_nonce=%@&oauth_signature=%@&oauth_signature_method=HMAC-SHA1&oauth_timestamp=%d&oauth_version=1.0",randomString, encodedString,interval]];
           
_request = [ASIFormDataRequest requestWithURL:url];
[_request setPostValue:@"json" forKey:@"format"];
[_request setPostValue:@"profile.create" forKey:@"method"];
[_request setPostValue:@"b753c99ccxxxxxx" forKey:@"oauth_consumer_key"];
[_request setPostValue:randomString forKey:@"oauth_nonce"];
[_request setPostValue:encodedString forKey:@"oauth_signature"];
[_request setPostValue:@"HMAC-SHA1" forKey:@"oauth_signature_method"];
[_request setPostValue:[NSNumber numberWithInt:interval] forKey:@"oauth_timestamp"];
[_request setPostValue:@"1.0" forKey:@"oauth_version"];

[_request setDelegate:self];
_request.timeOutSeconds = 60.0; 
[_request startAsynchronous];

}

我在上述代码中使用的方法的定义如下:

代码语言:javascript
复制
- (NSString *)hmacsha1:(NSString *)data secret:(NSString *)key {

const char *cKey  = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];

unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];

CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);

NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];

NSString *hash = [QSStrings encodeBase64WithData:HMAC];

NSLog(@"Hash: %@", hash);  

return hash;
}

NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

-(NSString *) genRandString {
//fixing length of 4 chars
NSMutableString *randomString = [NSMutableString stringWithCapacity: 4];

for (int i=0; i<4; i++) {
    [randomString appendFormat: @"%C", [letters characterAtIndex: arc4random() % [letters length]]];
}

return randomString;
}

- (NSString *)urlEncodeValue:(NSString *)str
{
NSMutableString * output = [NSMutableString string];
const unsigned char * source = (const unsigned char *)[str UTF8String];
int sourceLen = strlen((const char *)source);
for (int i = 0; i < sourceLen; ++i) {
    const unsigned char thisChar = source[i];
    if (thisChar == ' '){
        [output appendString:@"+"];
    } else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' || 
               (thisChar >= 'a' && thisChar <= 'z') ||
               (thisChar >= 'A' && thisChar <= 'Z') ||
               (thisChar >= '0' && thisChar <= '9')) {
        [output appendFormat:@"%c", thisChar];
    } else {
        [output appendFormat:@"%%%02X", thisChar];
    }
}
return output;
}

这里下载我的项目可以看到问题

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-05 22:59:49

最后,我自己发现了代码中的错误。近80%的问题已经得到解决。我在这个地方做错了:

代码语言:javascript
复制
NSString *requestString = [NSString stringWithFormat:@"POST&http%3A%2F%2Fplatform.fatsecret.com%2Frest%2Fserver.api&format%3Djson%26method%3Dprofile.create%26oauth_consumer_key%3Db753c99ccxxxxxx%26oauth_nonce%3D%@%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D%d%26oauth_version%3D1.0",randomString,interval];

在这里,我预先编码了基字符串。当我用某种格式初始化字符串时,它将http%3A%2F%2F作为某种未知格式,将其替换为0。因此,我将整个代码替换为:

代码语言:javascript
复制
- (void)viewDidLoad
{
[super viewDidLoad];

//for timestamp
NSTimeInterval intervalFloat = [[NSDate date] timeIntervalSince1970];
int interval = (int) intervalFloat;
NSLog(@"time interval: %d",interval);

//for oauth_nonce random string
NSString *randomString = [self genRandString];
NSLog(@"%@",randomString);

NSString *actualString = [NSString stringWithFormat:@"format=json&method=profile.create&oauth_consumer_key=b753c99ccd8****&oauth_nonce=%@&oauth_signature_method=HMAC-SHA1&oauth_timestamp=%d&oauth_version=1.0",randomString,interval];

 NSString *firstEncode = [self urlEncodeValue:actualString];

NSLog(@"first encode: %@",firstEncode);

NSMutableString *requestString = [[NSMutableString alloc] initWithString:@"GET&http%3A%2F%2Fplatform.fatsecret.com%2Frest%2Fserver.api&"];
[requestString appendString:firstEncode];
NSLog(@"base str: %@",requestString);

NSString *secret = @"395********&";

NSString *encodedStr = [self hmacsha1:requestString secret:secret];
NSLog(@"encodedStr: %@",encodedStr);

NSString *encodedString = [self urlEncodeValue:encodedStr];
NSLog(@"encodedString: %@",encodedString);

NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://platform.fatsecret.com/rest/server.api?format=json&method=profile.create&oauth_consumer_key=b753c99cc*******&oauth_nonce=%@&oauth_signature=%@&oauth_signature_method=HMAC-SHA1&oauth_timestamp=%d&oauth_version=1.0",randomString, encodedString,interval]];
NSLog(@"url: %@",url);

_request = [ASIFormDataRequest requestWithURL:url];
[_request setPostValue:@"json" forKey:@"format"];
[_request setPostValue:@"profile.create" forKey:@"method"];
[_request setPostValue:@"b753c9*********" forKey:@"oauth_consumer_key"];
[_request setPostValue:randomString forKey:@"oauth_nonce"];
[_request setPostValue:encodedString forKey:@"oauth_signature"];
[_request setPostValue:@"HMAC-SHA1" forKey:@"oauth_signature_method"];
[_request setPostValue:[NSNumber numberWithInt:interval] forKey:@"oauth_timestamp"];
[_request setPostValue:@"1.0" forKey:@"oauth_version"];

[_request setRequestMethod:@"GET"];
[_request addRequestHeader:@"Content-Type" value:@"application/json"];
[_request setDelegate:self];
_request.timeOutSeconds = 60.0; 
[_request startAsynchronous];

}

我希望这能帮上忙。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13218169

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档