Facebook a signé une request pour iOS (HMAC SHA256)

J'ai essayé de générer HMAC SHA256 pour Facebook request signée sur iOS depuis des semaines maintenant. J'ai désespérément besoin d'aide.

Les requests signées par Facebook comportent deux parties séparées par une période. La première partie est une HMAC256 de la charge utile alors que la seconde partie est une string codée Base64 de la charge utile. J'ai seulement pu recréer la deuxième partie.

 vlXgu64BQGFSQrY0ZcJBZASMvYvTHu9GQ0YM9rjPSso .  eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsIjAiOiJwYXlsb2FkIn0

J'ai utilisé le code suivant que tout le monde utilise mais il génère un hash différent:

#import <CommonCrypto/CommonHMAC.h> #import "NSData+Base64.h" +(NSSsortingng*) hmacForSecret:(NSSsortingng*)secret data:(NSSsortingng*)data { const char *cKey = [secret cSsortingngUsingEncoding:NSASCIISsortingngEncoding]; const char *cData = [data cSsortingngUsingEncoding:NSASCIISsortingngEncoding]; 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 base64EncodedSsortingng]; } 

Selon les docs de Facebook: https://developers.facebook.com/docs/authentication/signed_request/

La sortie correcte de HMAC256 devrait être en utilisant " secret " comme key:

  vlXgu64BQGFSQrY0ZcJBZASMvYvTHu9GQ0YM9rjPSso 

La charge utile à encoder:

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

REMARQUE: vous pouvez décoder Base64 la 2ème partie de la requête signée pour get cette charge utile.

Le problème était avec l'encodeur Base64. Il doit être encodé en Base64Url voir: http://en.wikipedia.org/wiki/Base64#URL_applications

Voici la méthode modifiée de la catégorie base64EncodedSsortingng:

 //NSData+Base64.h - (NSSsortingng *)base64EncodedSsortingng { size_t outputLength; char *outputBuffer = NewBase64Encode([self bytes], [self length], true, &outputLength); NSSsortingng *result = [[[NSSsortingng alloc] initWithBytes:outputBuffer length:outputLength encoding:NSASCIISsortingngEncoding] autorelease]; free(outputBuffer); NSSsortingng *b64PayloadClean = [[result componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedBySsortingng:@""]; //do URL encoding by replacing "+" and "/" to "-" and "_" respectively b64PayloadClean = [b64PayloadClean ssortingngByReplacingOccurrencesOfSsortingng:@"=" withSsortingng:@""]; b64PayloadClean = [b64PayloadClean ssortingngByReplacingOccurrencesOfSsortingng:@"+" withSsortingng:@"-"]; b64PayloadClean = [b64PayloadClean ssortingngByReplacingOccurrencesOfSsortingng:@"/" withSsortingng:@"_"]; return b64PayloadClean; }