简体   繁体   中英

Facebook Signed Request for iOS (HMAC SHA256)

I've been trying to generate HMAC SHA256 for Facebook signed request on iOS for weeks now. I am desperate need of help.

Facebook signed requests have two parts which are separated by a period. First part is an HMAC256 of the payload while the 2nd part is Base64 encoded string of the payload. I've only been able to recreate the second part.

vlXgu64BQGFSQrY0ZcJBZASMvYvTHu9GQ0YM9rjPSso.

I've been using the following code that everybody uses but it's generating a different hash:

#import <CommonCrypto/CommonHMAC.h>
#import "NSData+Base64.h"

+(NSString*) hmacForSecret:(NSString*)secret data:(NSString*)data {

     const char *cKey  = [secret cStringUsingEncoding:NSASCIIStringEncoding];
     const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
     unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];

     CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
     NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];

     return [HMAC base64EncodedString];
}

According to Facebook docs: https://developers.facebook.com/docs/authentication/signed_request/

Correct HMAC256 output should be when using " secret " as the key:

 vlXgu64BQGFSQrY0ZcJBZASMvYvTHu9GQ0YM9rjPSso

The payload to be encoded:

 {
     "algorithm": "HMAC-SHA256",
     "0": "payload"
 }

NOTE: You can Base64 decode the 2nd part of the signed request to get this payload.

The problem was with the Base64 encoder. It needs to be encoded as Base64Url see: http://en.wikipedia.org/wiki/Base64#URL_applications

Here's the modifed base64EncodedString category method:

//NSData+Base64.h
 - (NSString *)base64EncodedString
 {
    size_t outputLength;

    char *outputBuffer = NewBase64Encode([self bytes], [self length], true, &outputLength);
    NSString *result = [[[NSString alloc] initWithBytes:outputBuffer length:outputLength encoding:NSASCIIStringEncoding] autorelease];
    free(outputBuffer);

     NSString *b64PayloadClean = [[result componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""];

     //do URL encoding by replacing "+" and "/" to "-" and "_" respectively
     b64PayloadClean = [b64PayloadClean stringByReplacingOccurrencesOfString:@"=" withString:@""];
     b64PayloadClean = [b64PayloadClean stringByReplacingOccurrencesOfString:@"+" withString:@"-"];
     b64PayloadClean = [b64PayloadClean stringByReplacingOccurrencesOfString:@"/" withString:@"_"];

    return b64PayloadClean;
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM