我正在尝试生成oauth_signature以使用Fatsecret API,但是获得无效的签名错误 – 无法弄清楚原因.我尝试尽可能准确地遵循 
 here所述的所有步骤(参见步骤2)来生成签名值.他们说: 
  
  
 
Use the HMAC-SHA1 signature algorithm as defined by the [RFC2104] to sign the request where text is the Signature Base String and key is the concatenated values of the Consumer Secret and Access Secret separated by an ‘&’ 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 per [RFC2045],then escaped using the [RFC3986] percent-encoding (%xx) mechanism is the oauth_signature.
对于base64编码,我使用了QSStrings.h
我编码的步骤如下:
- (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",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];
} 
 我在上面的代码中使用的方法的定义如下:
- (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;
} 
 您可以通过从here下载我的项目来查看问题
解决方法
 我自己找到了代码中的错误.近80%的问题已经解决.我在这个地方做错了: 
  
  
 
        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",interval];
这里我预先编码了基本字符串.当我使用某种格式初始化字符串时,它将http://视为某种未知格式,将其替换为0.所以我将整个代码替换为:
- (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",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",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];
} 
 我希望这可以帮助别人.