具有 NSData 输入的 HMAC SHA1 Objective-C
HMAC SHA1 with NSData input Objective-C
我需要使用 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"字符串)与键相同:
const void *cData = [@"test" cStringUsingEncoding:NSUTF8StringEncoding];
然后使用此页面检查结果:HMAC crypt,结果匹配。
如果我对 NSString 进行哈希处理,那么我可以使用 cStringUsingEncoding:
,但我不知道如何将 NSData 转换为 const void*
。任何人都可以帮助我吗?谢谢!
我建议使用 CommonCrypto framework from Apple,因为您有硬件加速 SHA 计算。
我不知道它是不是 HMAC(据我所知它是受支持的,但没有尝试),但我会考虑切换你的服务器(或其他)以兼容,就像iOS 在硬件支持下速度要快得多。
编辑:您可以在此 SOF question.
阅读有关该主题的更多信息
编辑 2:在 Github 处还有一个用于 CommonCrypto 的 nice wrapper (Swift)。无论如何,它会让您了解如何实现它以及 CommonCrypto 支持什么。
Common Crypto 支持带 SHA1、MD5、SHA256、SHA384、SHA512 和 SHA224 的 HMAC。
这是一个稍微简单一些的示例实现,不确定它是否解决了您的问题,因为没有提供 input/desired 输出:
- (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;
}
我需要使用 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"字符串)与键相同:
const void *cData = [@"test" cStringUsingEncoding:NSUTF8StringEncoding];
然后使用此页面检查结果:HMAC crypt,结果匹配。
如果我对 NSString 进行哈希处理,那么我可以使用 cStringUsingEncoding:
,但我不知道如何将 NSData 转换为 const void*
。任何人都可以帮助我吗?谢谢!
我建议使用 CommonCrypto framework from Apple,因为您有硬件加速 SHA 计算。
我不知道它是不是 HMAC(据我所知它是受支持的,但没有尝试),但我会考虑切换你的服务器(或其他)以兼容,就像iOS 在硬件支持下速度要快得多。
编辑:您可以在此 SOF question.
阅读有关该主题的更多信息编辑 2:在 Github 处还有一个用于 CommonCrypto 的 nice wrapper (Swift)。无论如何,它会让您了解如何实现它以及 CommonCrypto 支持什么。
Common Crypto 支持带 SHA1、MD5、SHA256、SHA384、SHA512 和 SHA224 的 HMAC。
这是一个稍微简单一些的示例实现,不确定它是否解决了您的问题,因为没有提供 input/desired 输出:
- (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;
}