Objective-C sample code for HMAC-SHA1

I need to create HMAC-SHA1 in Objective C. But I did not find anything that works. I tried with CommonCrypto using CCHMAC but did not work. I need to generate hmac even after generating the HOTP number.

Does anyone have sample code in Objective-C or C?

+60
c objective-c hmac sha1
Apr 16 '09 at 14:50
source share
8 answers

Here you create the HMAC using SHA-256:

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

I do not know the HOTP library, but the algorithm was quite simple, if I remember correctly.

+73
Apr 16 '09 at 14:59
source share

here is how you can generate base64 HMAC-SHA1 .

You need to add Base64.h and Base64.m to your project. You can get it here .

If you use ARC, it will show some errors in Base64.m. Find strings similar to this

 return [[[self alloc] initWithBase64String:base64String] autorelease]; 

you need to delete the auto-ad section. The end result should look like this:

 return [[self alloc] initWithBase64String:base64String]; 

Now in your general project, import "Base64.h" and the following code

 #import "Base64.h" #include <CommonCrypto/CommonDigest.h> #include <CommonCrypto/CommonHMAC.h> - (NSString *)hmacsha1:(NSString *)data secret:(NSString *)key { const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding]; const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding]; 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)]; NSString *hash = [HMAC base64String]; return hash; } 

FROM

 NSLog(@"Hash: %@", hash); 

you will get something similar to this:

 ghVEjPvxwLN1lBi0Jh46VpIchOc= 

+36
Aug 28 2018-12-12T00:
source share

This is a complete solution that works without additional libraries or hacks:

 +(NSString *)hmac:(NSString *)plainText withKey:(NSString *)key { const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding]; const char *cData = [plainText cStringUsingEncoding:NSASCIIStringEncoding]; unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH]; CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC); NSData *HMACData = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)]; const unsigned char *buffer = (const unsigned char *)[HMACData bytes]; NSString *HMAC = [NSMutableString stringWithCapacity:HMACData.length * 2]; for (int i = 0; i < HMACData.length; ++i) HMAC = [HMAC stringByAppendingFormat:@"%02lx", (unsigned long)buffer[i]]; return HMAC; } 

You do not need to include a third-party base64 library as it is already encoded.

+22
May 9 '13 at 9:41
source share

This works without using custom protocols, using some code from http://cocoawithlove.com/2009/07/hashvalue-object-for-holding-md5-and.html

HashSHA256.h

 #import <Foundation/Foundation.h> #import <CommonCrypto/CommonDigest.h> @interface HashSHA256 : NSObject { } - (NSString *) hashedValue :(NSString *) key andData: (NSString *) data ; @end 

HashSHA256.m

 #import "HashSHA256.h" #import <CommonCrypto/CommonHMAC.h> @implementation HashSHA256 - (NSString *) hashedValue :(NSString *) key andData: (NSString *) data { const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding]; const char *cData = [data cStringUsingEncoding:NSUTF8StringEncoding]; unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH]; CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC); NSString *hash; NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2]; for(int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) [output appendFormat:@"%02x", cHMAC[i]]; hash = output; return hash; } @end 

Using:

 - (NSString *) encodePassword: (NSString *) myPassword { HashSHA256 * hashSHA256 = [[HashSHA256 alloc] init]; NSString * result = [hashSHA256 hashedValue:mySecretSalt andData:myPassword]; return result; } 
+8
Nov 27 '11 at 19:12
source share

I spend the whole day trying to convert the generated hash (bytes) into readable data. I used the basic encoded solution from the above answer, and it did not work at all for me (btw you need an external .h to be able to use the base64 encoding that I had).

So, I did this (which works fine without external .h):

 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); 
+2
Oct 12 '11 at 9:40
source share

Here's how you do it without external files returning the sixth line:

 -(NSString *)hmac:(NSString *)plaintext withKey:(NSString *)key { const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding]; const char *cData = [plaintext cStringUsingEncoding:NSASCIIStringEncoding]; unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH]; CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC); NSData *HMACData = [NSData dataWithBytes:cHMAC length:sizeof(cHMAC)]; const unsigned char *buffer = (const unsigned char *)[HMACData bytes]; NSMutableString *HMAC = [NSMutableString stringWithCapacity:HMACData.length * 2]; for (int i = 0; i < HMACData.length; ++i){ [HMAC appendFormat:@"%02x", buffer[i]]; } return HMAC; } 

It has been tested in xCode 5 with iOS 7 and works great!

+2
Oct 10 '13 at 17:40
source share

Of interest, why do you create (unsigned char cHMAC) and then convert to (NSData) and then convert to (NSMutableString) and then convert finally to (HexString)?

You could do it faster by cutting off the middleman (i.e. without NSData and NSMutableString as a whole, faster and better performance), also changing (unsigned char) to (uint8_t []), because they are all sixth -arrays anyway !, below:

 -(NSString *)hmac:(NSString *)plaintext withKey:(NSString *)key { const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding]; const char *cData = [plaintext cStringUsingEncoding:NSASCIIStringEncoding]; uint8_t cHMAC[CC_SHA1_DIGEST_LENGTH]; CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC); NSString *Hash1 = @""; for (int i=0; i< CC_SHA1_DIGEST_LENGTH; i++) { Hash1 = [Hash1 stringByAppendingString:[NSString stringWithFormat:@"%02X", cHMAC[i]]]; } return Hash1; } 

I hope this helps,

Hello

Hyder Sati

+1
Nov 08 '13 at 4:39
source share

Have you seen the Jens Alfke new MyCrypto classes?

He has sample code on his blog .

0
Apr 16 '09 at 15:23
source share



All Articles