Need to generate HMAC SHA256 hash in Objective C as in Java
hash, hmac, java, objective-c
Solution
You need to fix your Java hmac printer, because `4effffffd8ffffffce7cffffffc4ffffffc71b2f72ffffffdc21ffffffa1ffffffe0ffffffe62d32550b0771296bffffff9c1159ffffffdeffffff8675ffffff9928654c` isn't valid. All those `ffffff` in there are a giveaway that you are sign-extending the bytes to 32-bit signed integers before converting them to hex. Presumably the correct hmac is `4ed8ce7cc4c71b2f72dc21a1e0e62d32550b0771296b9c1159de86759928654c`.
Anyway, I suspect you are calling your method incorrectly. I copied your code into a test program which gives me this output for your key and data:
2011-12-10 13:03:38.231 hmactest[8251:707] test hmac = <4ed8ce7c c4c71b2f 72dc21a1 e0e62d32 550b0771 296b9c11 59de8675 9928654c>
That matches your desired output (except for the sign-extension errors).
Here's my test program:
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonHMAC.h>
NSData *hmacForKeyAndData(NSString *key, NSString *data)
{
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
return [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
}
int main (int argc, const char * argv[])
{
@autoreleasepool {
// Compare to http://en.wikipedia.org/wiki/HMAC#Examples_of_HMAC_.28MD5.2C_SHA1.2C_SHA256_.29
NSLog(@"empty hmac = %@", hmacForKeyAndData(@"", @""));
NSLog(@"test hmac = %@", hmacForKeyAndData(@"YARJSuwP5Oo6/r47LczzWjUx/T8ioAJpUK2YfdI/ZshlTUP8q4ujEVjC0seEUAAtS6YEE1Veghz+IDbNQb+2KQ==", @"id=456|time=19:10|nonce=8"));
}
return 0;
}
Problem
I need to generate a hash using HMAC SHA256. I am using the following code in Java. I need an equivalent code in Objective-C. ``` javax.crypto.Mac mac = javax.crypto.Mac.getInstance(type); javax.crypto.spec.SecretKeySpec secret = new javax.crypto.spec.SecretKeySpec(key.getBytes(), type); mac.init(secret); byte[] digest = mac.doFinal(value.getBytes()); StringBuilder sb = new StringBuilder(digest.length * 2); String s=""; for (byte b: digest) { s = Integer.toHexString(b); if (s.length() == 1) { sb.append('0'); } sb.append(s); } return sb.toString(); ``` Key = `YARJSuwP5Oo6/r47LczzWjUx/T8ioAJpUK2YfdI/ZshlTUP8q4ujEVjC0seEUAAtS6YEE1Veghz+IDbNQb+2KQ==` Value = `id=456|time=19:10|nonce=8` Output = ``` 4effffffd8ffffffce7cffffffc4ffffffc71b2f72ffffffdc21ffffffa1ffffffe0ffffffe62d32550b0771296bffffff9c1159ffffffdeffffff8675ffffff9928654c ``` I have this Objective-C function: ``` //Hash method Definition - (NSString *)getHashEncription:(NSString *)key andData:(NSString *)data{ NSLog(@"Secret Key %@ And Data %@", key, data); const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding]; const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding]; unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH]; //HmacSHA256 CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC); NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)]; [Base64 initialize]; NSString *b64EncStr = [Base64 encode:HMAC]; NSLog(@"Base 64 encoded = %@",b64EncStr); NSLog(@"NSData Value %@", HMAC); // unsigned char hashedChars[32]; // NSString *inputString; // inputString = [NSString stringWithFormat:@"hello"]; // NSData * inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding]; // CC_SHA256(inputData.bytes, inputData.length, hashedChars); return [[NSString alloc] initWithData:HMAC encoding:NSASCIIStringEncoding]; }//End of getHashEncription ``` The output that I am getting is this: ``` 8736bc4aa7fc3aa071f2b4262b6972a89d2861559a20afa765e46ff17cb181a9 ``` I tried removing the base64 encoding, but it didn't work. Any suggestions are most welcome.