【问题标题】:HMAC SHA1 with NSData input Objective-C带有 NSData 输入 Objective-C 的 HMAC SHA1
【发布时间】:2016-01-09 21:21:08
【问题描述】:

我需要使用 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];

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

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

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

如果我散列一个 NSString,那么我可以使用 cStringUsingEncoding:,但我无法将 NSData 转换为 const void*。任何人都可以帮助我吗?谢谢!

【问题讨论】:

    标签: objective-c encryption hmac


    【解决方案1】:

    Common Crypto 支持带有 SHA1、MD5、SHA256、SHA384、SHA512 和 SHA224 的 HMAC。

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

    - (NSString *)HMACSHA1:(NSData *)data {
        NSParameterAssert(data);
    
        NSData *keyData = [@"SampleSecretKey012345678" dataUsingEncoding:NSUTF8StringEncoding];
        NSMutableData *hMacOut = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH];
    
        CCHmac(kCCHmacAlgSHA1,
               keyData.bytes, keyData.length,
               data.bytes,    data.length,
               hMacOut.mutableBytes);
    
        /* Returns hexadecimal string of NSData. Empty string if data is empty. */
        NSString *hexString = @"";
        if (data) {
            uint8_t *dataPointer = (uint8_t *)(hMacOut.bytes);
            for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) {
                hexString = [hexString stringByAppendingFormat:@"%02x", dataPointer[i]];
            }
        }
    
        return hexString;
    }
    

    【讨论】:

    • 谢谢你,这行得通!我从没想过只使用data.bytesdata.lenght 而不是将数据转换为cString。多么愚蠢。
    【解决方案2】:

    我建议您使用CommonCrypto framework from Apple,因为您有硬件加速的 SHA 计算。

    我不知道它是否是 HMAC(据我所知,它受支持,但没有尝试),但我会考虑将您的服务器(或其他)切换为兼容,就像在 iOS 端一样有了硬件支持,速度要快得多。

    编辑:您可以在SOF question 阅读有关该主题的更多信息。

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

    【讨论】:

    • 感谢您的建议,我想我仍然需要阅读更多关于密码学的内容才能理解这些内容:)
    猜你喜欢
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 2013-05-22
    • 1970-01-01
    • 2012-10-12
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多