I need to hash a NSData input with HMAC-SHA1. I used this code:
- (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];
}
but the hex string output is always wrong (checked from server). I think the problem is this line:
const void *cData = [data bytes];
because if convert data (sample "test" string) in the same way as key:
const void *cData = [@"test" cStringUsingEncoding:NSUTF8StringEncoding];
then check the result using this page: HMAC crypt, the result is matched.
If I hash a NSString then I can use cStringUsingEncoding: but I can't figure out convert NSData to const void*. Anyone can help me? Thanks!
Common Crypto supports HMAC with SHA1, MD5, SHA256, SHA384, SHA512 and SHA224.
Here is an example implementation that is a little simpler, not sure if it resolves yourproblem since no input/desired output was supplied:
- (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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With