質問

I am trying to implement HMAC authentication from Objective C(CCHmac) and PHP (hash_hmac). I got the different hash result. Have anyone can help me? I don't know why to get the different hash result? Below is my Code (Objective-c & PHP) for your reference. Please!

PHP:

$APIConsumerSecret ="DcmzvkQC7Sno+lxnbDG0hTtZ0WTQn9T2T9DJxEmcB0";
$APIConsumerSecret = urlencode($APIConsumerSecret).'&';
$BaseString="GET&http%3A%2F%2Fboday.api.simppo.com%2Foauth%2Frequest_token&oauth_consumer_key%3DCN6W1I8E2CEWZJNQI2KA7KY3%26oauth_nonce%3DlxTSJL%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1357268295%26oauth_version%3D1.0";

echo base64_encode(hash_hmac('sha1',$BaseString,$APIConsumerSecret,true));

PHP Result: xJ5Ya4u4ghH4ugIieGIb9AcFpD0=

Objective-C

- (NSString*)flickr_oauthSignatureFor:(NSString*)dataString withKey:(NSString*)secret
{
  NSData* secretData = [secret dataUsingEncoding:NSUTF8StringEncoding];
  NSData* stringData = [dataString dataUsingEncoding:NSUTF8StringEncoding];

  const void* keyBytes = [secretData bytes];
  const void* dataBytes = [stringData bytes];

  ///#define CC_SHA1_DIGEST_LENGTH   20          /* digest length in bytes */
  void* outs = malloc(CC_SHA1_DIGEST_LENGTH);

  CCHmac(kCCHmacAlgSHA1, keyBytes, [secretData length], dataBytes, [stringData length], outs);

  // Soluion 1
  NSData* signatureData = [NSData dataWithBytesNoCopy:outs length:CC_SHA1_DIGEST_LENGTH freeWhenDone:YES];

  NSLog(@"D1-0: signatureData %@", signatureData );
  NSLog(@"base64:%@", [signatureData base64EncodedString] );

  return [signatureData base64EncodedString];
}

Objective-C Result:

D1-0: <59052771 e670a04b 3a2e87db 3d7965be 1aed112e>
base64: WQUnceZwoEs6LofbPXllvhrtES4=
役に立ちましたか?

解決

In the example php is URL encoding, the ObjectiveC is not.

Best to start with a simple example, short strings and skip the base64 encoding on both, Then compare results. When this works start adding the additional operations such as url encoding and base 64.

For php start with: echo hash_hmac('sha1', 'test string', 'secret'); and the same in objc.

Here is a starting point that matches php:

NSString* phpsignatureData = @"dd26bfddf122c1055d4cd5b054227727e1e3eecf";
NSLog(@"phpsignatureData: %@", phpsignatureData);

NSData* secretData = [@"secret" dataUsingEncoding:NSUTF8StringEncoding];
NSData* stringData = [@"test string" dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData *signatureData = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1, secretData.bytes, secretData.length, stringData.bytes, stringData.length, signatureData.mutableBytes);

NSLog(@"secretData %@", secretData );
NSLog(@"stringData %@", stringData );
NSLog(@"signatureData %@", signatureData );

NSLog output:

phpsignatureData: dd26bfddf122c1055d4cd5b054227727e1e3eecf
secretData <73656372 6574>   
stringData <74657374 20737472 696e67>   
signatureData <dd26bfdd f122c105 5d4cd5b0 54227727 e1e3eecf>

他のヒント

You can try this: (Objective C)

-(NSString *)DATA_TO_HeX_With_HmacDigestData:(NSData *)digestData{
    const unsigned char *dataBuffer = (const unsigned char *)[digestData bytes];
    NSUInteger          dataLength  = [digestData length];
    NSMutableString     *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
    for (int i = 0; i < dataLength; ++i)
    {
        [hexString appendFormat:@"%02x", (unsigned int)dataBuffer[i]];
    }
    return [NSString stringWithString:hexString];
}

-(NSString *)HMAC_CREATOR:(NSString *)str andKeyData:(NSData *)keyData  {

    NSData *signatureData = [str dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t digest[CC_SHA256_DIGEST_LENGTH]={0};
    CCHmacContext context;
    CCHmacInit(&context, kCCHmacAlgSHA256, keyData.bytes, keyData.length);
    CCHmacUpdate(&context, signatureData.bytes, signatureData.length);
    CCHmacFinal(&context, digest);
    NSData *digestData = [NSData dataWithBytes:digest length:sizeof(digest)];
    return [self DATA_TO_HeX_With_HmacDigestData:digestData];
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top