Invalid signature: oauth_signature

I'm trying to create oauth_signature to use the Fatsecret API , but getting an invalid signature error - can't figure out why. I tried to follow all the steps mentioned here (see Step 2) to generate the Signature value as accurately as possible. They speak:

Use the HMAC-SHA1 signature algorithm as defined in [RFC2104] to sign a request in which the text is the signature baseline and the key is the concatenated user secrecy and access secrecy separated by "&"; character (show '&', even if Access Secret is empty, as some methods do not require an access token).

The calculated digest octet string, first base64 encoded on [RFC2045], and then escaped using the [percent encoding (% xx) [RFC3986]) mechanism, is oauth_signature.

For base64 encoding, I used QSStrings.h

The steps that I encoded are as follows:

- (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]; } 

The definitions for the methods that I used in the above code are as follows:

 - (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; } 

You can see the problem by downloading my project from here

+7
source share
1 answer

Atlast I myself calculated the errors in the code. The problem is solved by 80%. I was wrong in this place:

 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]; 

Here I precoded the base line. Since I initialize a string with some format, it took http%3A%2F%2F as some unknown format, replacing it with 0. Therefore, I replaced the whole code as follows:

 - (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]; } 

I hope this helps someone.

+6
source

All Articles