带有NSData输入的HMAC SHA1 Objective-C

时间:2015-10-12 11:50:02

标签: objective-c encryption hmac

我需要使用HMAC-SHA1散列NSData输入。我用了这段代码:

- (NSString *)HMACSHA1:(NSData *)data {
    NSParameterAssert(data);

    const char *cKey = [@"SampleSecretKey012345678" cStringUsingEncoding:NSUTF8StringEncoding];
    const void *cData = [data bytes];

    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)];\

    /* Returns hexadecimal string of NSData. Empty string if data is empty. */

    const unsigned char *dataBuffer = (const unsigned char *)[HMAC bytes];

    if (!dataBuffer) {
        return [NSString string];
    }

    NSUInteger dataLength = [HMAC 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];
}

但十六进制字符串输出始终错误(从服务器检查)。我认为问题在于这一行:

const void *cData = [data bytes];

因为如果转换数据(示例“test”字符串)的方式与key相同:

const void *cData = [@"test" cStringUsingEncoding:NSUTF8StringEncoding];

然后使用此页面检查结果:HMAC crypt,结果匹配。

如果我对一个NSString进行哈希,那么我可以使用cStringUsingEncoding:,但我无法弄清楚将NSData转换为const void*。有人可以帮帮我吗?谢谢!

2 个答案:

答案 0 :(得分:2)

Common Crypto支持HMAC,包括SHA1,MD5,SHA256,SHA384,SHA512和SHA224。

这是一个更简单的示例实现,不确定它是否解决了您的问题,因为没有提供输入/所需的输出:

$url = "http://www.example.com/";
$ch = curl_init();  
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$page = curl_exec($ch);
curl_close($ch);
echo $page;

答案 1 :(得分:0)

我建议您使用CommonCrypto framework from Apple进行硬件加速SHA计算。

我不知道它是否是HMAC(据我所知,它支持,但没有尝试),但我会考虑切换你的服务器(或其他)兼容,如在iOS端硬件支持会更快。

修改:您可以在此SOF question了解有关该主题的更多信息。

编辑2 :在Github上,还有一个nice wrapper(Swift)用于CommonCrypto。无论如何,它会让你知道如何实现它以及CommonCrypto支持什么。