Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HmacSHA256 objective-c encryptation

I wanna encpryt a string with a key, using HmacSHA256. The code everyone use is the one below, but there is one thing that doesn´t make sense. Why would we use base64 at the end if all we want is the HmacSHA256 hash?

I tried seeing the hash generated after the method CCHmac is called with

NSString *str = [[NSString alloc] initWithData:HMAC encoding:NSASCIIStringEncoding];
NSLog(@"%@", str);

But i don´t get the hash generated, i get null, or garbage, like this:

2011-10-11 09:38:05.082 Hash_HmacSHA256[368:207] (null) 2011-10-11 09:38:05.085 Hash_HmacSHA256[368:207] Rwªb7iså{yyþ§Ù(&oá÷ÛËÚ¥M`f

import < CommonCrypto/CommonHMAC.h>

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

NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC
                                  length:sizeof(cHMAC)];

NSString *hash = [HMAC base64Encoding]; //This line doesn´t make sense

[key release];
[data release];
like image 413
bruno Avatar asked Dec 21 '22 07:12

bruno


2 Answers

First of all, for those wondering, this is in reference to my answer to this question: Objective-C sample code for HMAC-SHA1


The HMAC you generate is a 256-bit binary value that may or may not start with a 0 byte.

To be able to print it, you need a string representation (binary, hex, decimal, base64, etc.). Base64 is one of the most efficient among these, that's why I used a Base64 encoding there.

The reason you get garbage is that most (if not all) of the octets in the HMAC value are outside the range of printable ASCII characters. If the first octet is 0 (0x00), you get nil. This is why you need an encoding that supports arbitrary values. ASCII doesn't.

Of course, if you don't want to print the HMAC value, then may not need such an encoding, and can keep the HMAC as is (binary NSData).

like image 51
Can Berk Güder Avatar answered Jan 05 '23 01:01

Can Berk Güder


I spend a whole day, trying to convert the generated hash (bytes) into readable data. I used the base64 encoded you said and it didn´t work at all for me .

So what i did was this:

CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);

// Now convert to NSData structure to make it usable again
NSData *out = [NSData dataWithBytes:cHMAC length:CC_SHA256_DIGEST_LENGTH];

// description converts to hex but puts <> around it and spaces every 4 bytes
NSString *hash = [out description];
hash = [hash stringByReplacingOccurrencesOfString:@" " withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@"<" withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@">" withString:@""];
// hash is now a string with just the 40char hash value in it
NSLog(@"%@",hash);
like image 45
bruno Avatar answered Jan 05 '23 02:01

bruno