我正在尝试从目标C(CCHmac)和PHP (hash_hmac)实现HMAC认证。我得到了不同的哈希结果。有人能帮我吗?我不知道为什么会得到不同的哈希结果?下面是我的代码(Objective-c &PHP)供您参考。拜托!
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=
- (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];
}
目标- c结果:
D1-0: <59052771 e670a04b 3a2e87db 3d7965be 1aed112e>
base64: WQUnceZwoEs6LofbPXllvhrtES4=
在示例中php是URL编码,ObjectiveC不是。
最好从一个简单的例子开始,短字符串并跳过base64编码,然后比较结果。当它工作时,开始添加额外的操作,如url编码和base 64。
echo hash_hmac('sha1', 'test string', 'secret');在objc. 中也是如此。这里是一个匹配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输出:
phpsignatureData: dd26bfddf122c1055d4cd5b054227727e1e3eecf secretData <73656372 6574> stringData <74657374 20737472 696e67> signatureData <dd26bfdd f122c105 5d4cd5b0 54227727 e1e3eecf>
你可以试试这个:(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];
}