Objective-C sample code for HMAC-SHA1 [closed]

匿名 (未验证) 提交于 2019-12-03 02:08:02

问题:

I need to generate HMAC-SHA1 in Objective C. But i didnt find anything that works. I tried with CommonCrypto, using CCHMAC, but didnt works. I need to generate a hmac and after generate HOTP number.

Somebody have any example code in Objective C or C?

回答1:

Here's how you generate an 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'm not aware of an HOTP library, but the algorithm was quite simple, if I recall correctly.



回答2:

here is how you can generate HMAC-SHA1 base64.

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

If you use ARC, it will show some errors in Base64.m. Find the lines who are similar like this

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

what you need is to delete the autorelease section. The final result should look like:

return [[self alloc] initWithBase64String:base64String]; 

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

#import "Base64.h" #include  #include   - (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; } 

With

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

you will get something similar to this:

ghVEjPvxwLN1lBi0Jh46VpIchOc= 



回答3:

This is the complete solution which works without any extra 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 

You don't have to include any third-party base64 library as it is already encoded.



回答4:

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  #import   @interface HashSHA256 : NSObject {   }   - (NSString *) hashedValue :(NSString *) key andData: (NSString *) data ;   @end 

HashSHA256.m

#import "HashSHA256.h"  #import    @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 

Usage:

- (NSString *) encodePassword: (NSString *) myPassword {     HashSHA256 * hashSHA256 = [[HashSHA256 alloc] init];        NSString * result = [hashSHA256 hashedValue:mySecretSalt andData:myPassword];            return result;        } 


回答5:

So what I did was this (which works perfectly without an 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 is now a string with just the 40char hash value in it NSLog(@"%@",hash); 


回答6:

This is how yo do it without external files returning an hex string:

-(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 

It was tested in xCode 5 with iOS 7 and works fine!



回答7:

Out of interest, why do you create (unsigned char cHMAC) and then convert into (NSData) and then convert it into (NSMutableString) and then convert finally into (HexString)?

You could do this in a quicker way by cutting the middleman (i.e. without NSData and NSMutableString altogether, quicker and better performance), also changing (unsigned char) into (uint8_t []), after all they are all hex-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

I hope this helps,

Regards

Heider Sati



回答8:

Have you seen Jens Alfke's new MyCrypto classes?

He has some sample code on his blog.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!